diff --git a/.gitignore b/.gitignore index 8c7053826c..1eaa7fe66c 100755 --- a/.gitignore +++ b/.gitignore @@ -118,19 +118,23 @@ tags # PlatformIO files/dirs .pio* +.pioenvs +.piolibdeps lib/readme.txt #Visual Studio *.sln *.vcxproj *.vcxproj.filters -Marlin/Release/ -Marlin/Debug/ -Marlin/__vm/ -Marlin/.vs/ +Release/ +Debug/ +__vm/ +.vs/ +vc-fileutils.settings #VScode .vscode +.vscode/c_cpp_properties.json #cmake CMakeLists.txt diff --git a/.travis.yml b/.travis.yml index 93a365a721..710bd364ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,10 @@ install: - git clone https://github.com/teemuatlut/TMC2130Stepper.git - sudo mv TMC2130Stepper /usr/local/share/arduino/libraries/TMC2130Stepper # + # Install: TMC2208 Stepper Motor Controller library + - git clone https://github.com/teemuatlut/TMC2208Stepper.git + - sudo mv TMC2208Stepper /usr/local/share/arduino/libraries/TMC2208Stepper + # # Install: Adafruit Neopixel library - git clone https://github.com/adafruit/Adafruit_NeoPixel.git - sudo mv Adafruit_NeoPixel /usr/local/share/arduino/libraries/Adafruit_NeoPixel @@ -86,11 +90,11 @@ script: - opt_set TEMP_SENSOR_0 -2 - opt_set TEMP_SENSOR_1 1 - opt_set TEMP_SENSOR_BED 1 - - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES + - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS - - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_RGBW_LED - - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE - - opt_enable_adv FWRETRACT MAX7219_DEBUG + - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED + - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE + - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU - opt_set ABL_GRID_POINTS_X 16 - opt_set ABL_GRID_POINTS_Y 16 - opt_set_adv FANMUX0_PIN 53 @@ -99,20 +103,15 @@ script: # Test a probeless build of AUTO_BED_LEVELING_UBL # - restore_configs - - opt_enable AUTO_BED_LEVELING_UBL UBL_G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS G3D_PANEL - - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING + - opt_enable AUTO_BED_LEVELING_UBL DEBUG_LEVELING_FEATURE G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS EEPROM_CHITCHAT G3D_PANEL + - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING NANODLP_Z_SYNC - build_marlin # - # And with a probe... + # Add a Sled Z Probe, use UBL Cartesian moves # - - opt_enable FIX_MOUNTED_PROBE - - build_marlin - # - # Test a Sled Z Probe - # ...with AUTO_BED_LEVELING_LINEAR, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, and EEPROM_CHITCHAT - # - - restore_configs - - opt_enable Z_PROBE_SLED AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT + - opt_enable Z_PROBE_SLED SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE + - opt_disable SEGMENT_LEVELED_MOVES + - opt_enable_adv BABYSTEP_ZPROBE_OFFSET DOUBLECLICK_FOR_Z_BABYSTEPPING - build_marlin # # Test a Servo Probe @@ -122,23 +121,34 @@ script: - opt_enable NUM_SERVOS Z_ENDSTOP_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE - opt_set NUM_SERVOS 1 - opt_enable AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT - - opt_enable_adv EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET + - opt_enable_adv NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET - build_marlin # # Test MESH_BED_LEVELING feature, with LCD # - restore_configs - - opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER + - opt_enable MESH_BED_LEVELING G26_MESH_EDITING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER - build_marlin # - # Test PROBE_MANUALLY feature, with LCD support, + # Test MINIRAMBO for PWM_MOTOR_CURRENT + # PROBE_MANUALLY feature, with LCD support, + # ULTIMAKERCONTROLLER, FILAMENT_LCD_DISPLAY, FILAMENT_WIDTH_SENSOR, + # PRINTCOUNTER, NOZZLE_PARK_FEATURE, NOZZLE_CLEAN_FEATURE, PCA9632, + # Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS, BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS, + # ADVANCED_PAUSE_FEATURE, PARK_HEAD_ON_PAUSE, LCD_INFO_MENU, # EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER, # INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT # - restore_configs - opt_set MOTHERBOARD BOARD_MINIRAMBO - - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR LCD_BED_LEVELING ULTIMAKERCONTROLLER + - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR G26_MESH_EDITING LCD_BED_LEVELING ULTIMAKERCONTROLLER - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT + - opt_enable ULTIMAKERCONTROLLER SDSUPPORT + - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG + - opt_enable_adv BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS + - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU M114_DETAIL + - opt_set_adv PWM_MOTOR_CURRENT {1300,1300,1250} + - opt_set_adv I2C_SLAVE_ADDRESS 63 - build_marlin # # Test 5 extruders on AZTEEG_X3_PRO (can use any board with >=5 extruders defined) @@ -191,34 +201,29 @@ script: - opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER - build_marlin # - # Test MINIRAMBO for PWM_MOTOR_CURRENT - # ULTIMAKERCONTROLLER, FILAMENT_LCD_DISPLAY, FILAMENT_WIDTH_SENSOR, - # PRINTCOUNTER, NOZZLE_PARK_FEATURE, NOZZLE_CLEAN_FEATURE, PCA9632, - # Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS, BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS, - # ADVANCED_PAUSE_FEATURE, PARK_HEAD_ON_PAUSE, LCD_INFO_MENU, - # - - restore_configs - - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT - - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 - - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS - - opt_set_adv I2C_SLAVE_ADDRESS 63 - - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU - - pins_set RAMPS X_MAX_PIN -1 - - opt_set_adv Z2_MAX_PIN 2 - - build_marlin - # # Enable COREXY # - restore_configs - opt_enable COREXY - build_marlin # - # Enable COREYX (swapped) - # - #- restore_configs - #- opt_enable COREYX - #- build_marlin + # Test many less common options # + - restore_configs + - opt_enable COREYX + - opt_set_adv FAN_MIN_PWM 50 + - opt_set_adv FAN_KICKSTART_TIME 100 + - opt_set_adv XY_FREQUENCY_LIMIT 15 + - opt_enable_adv SHOW_TEMP_ADC_VALUES HOME_Y_BEFORE_X EMERGENCY_PARSER FAN_KICKSTART_TIME + - opt_enable_adv ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED ADVANCED_OK + - opt_enable_adv VOLUMETRIC_DEFAULT_ON NO_WORKSPACE_OFFSETS ACTION_ON_KILL + - opt_enable_adv EXTRA_FAN_SPEED FWERETRACT Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS + - opt_enable_adv MENU_ADDAUTOSTART SDCARD_SORT_ALPHA + - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER + - opt_enable FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR + - opt_enable ENDSTOP_INTERRUPTS_FEATURE FAN_SOFT_PWM SDSUPPORT + - opt_enable USE_XMAX_PLUG + - build_marlin # ######## Other Standard LCD/Panels ############## # @@ -252,7 +257,7 @@ script: # - restore_configs - opt_enable G3D_PANEL SDSUPPORT - - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING + - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES - opt_set_adv SDSORT_GCODE true - opt_set_adv SDSORT_USES_RAM true - opt_set_adv SDSORT_USES_STACK true @@ -263,7 +268,7 @@ script: # - restore_configs - opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT - - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING + - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES - build_marlin # # REPRAPWORLD_KEYPAD @@ -326,7 +331,7 @@ script: # - use_example_configs delta/generic - opt_disable DISABLE_MIN_ENDSTOPS - - opt_enable AUTO_BED_LEVELING_UBL Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT OLED_PANEL_TINYBOY2 + - opt_enable AUTO_BED_LEVELING_UBL Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT OLED_PANEL_TINYBOY2 MESH_EDIT_GFX_OVERLAY - build_marlin # # Delta Config (FLSUN AC because it's complex) @@ -344,7 +349,14 @@ script: - use_example_configs SCARA - opt_enable AUTO_BED_LEVELING_BILINEAR FIX_MOUNTED_PROBE USE_ZMIN_PLUG EEPROM_SETTINGS EEPROM_CHITCHAT ULTIMAKERCONTROLLER - opt_enable_adv HAVE_TMC2130 X_IS_TMC2130 Y_IS_TMC2130 Z_IS_TMC2130 - - opt_enable_adv AUTOMATIC_CURRENT_CONTROL STEALTHCHOP HYBRID_THRESHOLD SENSORLESS_HOMING + - opt_enable_adv MONITOR_DRIVER_STATUS STEALTHCHOP HYBRID_THRESHOLD TMC_DEBUG SENSORLESS_HOMING + - build_marlin + # + # TMC2208 Config + # + - restore_configs + - opt_enable_adv HAVE_TMC2208 X_IS_TMC2208 Y_IS_TMC2208 Z_IS_TMC2208 + - opt_enable_adv MONITOR_DRIVER_STATUS STEALTHCHOP HYBRID_THRESHOLD TMC_DEBUG - build_marlin # # tvrrug Config need to check board type for sanguino atmega644p diff --git a/Marlin/Conditionals_LCD.h b/Marlin/Conditionals_LCD.h index b5b476a60d..423552fedb 100644 --- a/Marlin/Conditionals_LCD.h +++ b/Marlin/Conditionals_LCD.h @@ -42,7 +42,7 @@ #define U8GLIB_ST7565_64128N - #elif ENABLED(ANET_KEYPAD_LCD) + #elif ENABLED(ZONESTAR_LCD) #define REPRAPWORLD_KEYPAD #define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 @@ -53,6 +53,7 @@ // this helps to implement ADC_KEYPAD menus #define ENCODER_PULSES_PER_STEP 1 #define ENCODER_STEPS_PER_MENU_ITEM 1 + #define ENCODER_FEEDRATE_DEADZONE 2 #define REVERSE_MENU_DIRECTION #elif ENABLED(ANET_FULL_GRAPHICS_LCD) @@ -62,7 +63,6 @@ #elif ENABLED(BQ_LCD_SMART_CONTROLLER) #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER - #define LONG_FILENAME_HOST_SUPPORT #elif ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) @@ -125,6 +125,11 @@ #define REPRAP_DISCOUNT_SMART_CONTROLLER #define U8GLIB_SH1106 + #elif ENABLED(MKS_12864OLED_SSD1306) + + #define REPRAP_DISCOUNT_SMART_CONTROLLER + #define U8GLIB_SSD1306 + #elif ENABLED(MKS_MINI_12864) #define MINIPANEL @@ -155,7 +160,7 @@ #endif - #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(LCD_FOR_MELZI) + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(LCD_FOR_MELZI) || ENABLED(SILVER_GATE_GLCD_CONTROLLER) #define DOGLCD #define U8GLIB_ST7920 #define REPRAP_DISCOUNT_SMART_CONTROLLER @@ -306,7 +311,7 @@ #define LCD_STR_FILAM_DIA "\xf8" #define LCD_STR_FILAM_MUL "\xa4" #else - /* Custom characters defined in the first 8 characters of the LCD */ + // Custom characters defined in the first 8 characters of the LCD #define LCD_BEDTEMP_CHAR 0x00 // Print only as a char. This will have 'unexpected' results when used in a string! #define LCD_DEGREE_CHAR 0x01 #define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation @@ -453,13 +458,6 @@ */ #define HAS_Z_SERVO_ENDSTOP (defined(Z_ENDSTOP_SERVO_NR) && Z_ENDSTOP_SERVO_NR >= 0) - /** - * UBL has its own manual probing, so this just causes trouble. - */ - #if ENABLED(AUTO_BED_LEVELING_UBL) - #undef PROBE_MANUALLY - #endif - /** * Set a flag for any enabled probe */ diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h index dc6f212364..9b69e1ffcb 100644 --- a/Marlin/Conditionals_post.h +++ b/Marlin/Conditionals_post.h @@ -89,7 +89,7 @@ #define CORE_AXIS_1 B_AXIS #define CORE_AXIS_2 C_AXIS #endif - #if (ENABLED(COREYX) || ENABLED(COREZX) || ENABLED(COREZY)) + #if ENABLED(COREYX) || ENABLED(COREZX) || ENABLED(COREZY) #define CORESIGN(n) (-(n)) #else #define CORESIGN(n) (n) @@ -378,29 +378,122 @@ #define ARRAY_BY_HOTENDS(...) ARRAY_N(HOTENDS, __VA_ARGS__) #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1) + /** + * X_DUAL_ENDSTOPS endstop reassignment + */ + #if ENABLED(X_DUAL_ENDSTOPS) + #if X_HOME_DIR > 0 + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN X_MIN_PIN + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN X_MAX_PIN + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN Y_MIN_PIN + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN Y_MAX_PIN + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN Z_MIN_PIN + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN Z_MAX_PIN + #else + #define X2_MAX_ENDSTOP_INVERTING false + #endif + #define X2_MIN_ENDSTOP_INVERTING false + #else + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN X_MIN_PIN + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN X_MAX_PIN + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN Y_MIN_PIN + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN Y_MAX_PIN + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN Z_MIN_PIN + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN Z_MAX_PIN + #else + #define X2_MIN_ENDSTOP_INVERTING false + #endif + #define X2_MAX_ENDSTOP_INVERTING false + #endif + #endif + + // Is an endstop plug used for the X2 endstop? + #define IS_X2_ENDSTOP(A,M) (ENABLED(X_DUAL_ENDSTOPS) && X2_USE_ENDSTOP == _##A##M##_) + + /** + * Y_DUAL_ENDSTOPS endstop reassignment + */ + #if ENABLED(Y_DUAL_ENDSTOPS) + #if Y_HOME_DIR > 0 + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN X_MIN_PIN + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN X_MAX_PIN + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN Y_MIN_PIN + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN Y_MAX_PIN + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN Z_MIN_PIN + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN Z_MAX_PIN + #else + #define Y2_MAX_ENDSTOP_INVERTING false + #endif + #define Y2_MIN_ENDSTOP_INVERTING false + #else + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN X_MIN_PIN + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN X_MAX_PIN + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN Y_MIN_PIN + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN Y_MAX_PIN + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN Z_MIN_PIN + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN Z_MAX_PIN + #else + #define Y2_MIN_ENDSTOP_INVERTING false + #endif + #define Y2_MAX_ENDSTOP_INVERTING false + #endif + #endif + + // Is an endstop plug used for the Y2 endstop or the bed probe? + #define IS_Y2_ENDSTOP(A,M) (ENABLED(Y_DUAL_ENDSTOPS) && Y2_USE_ENDSTOP == _##A##M##_) + /** * Z_DUAL_ENDSTOPS endstop reassignment */ #if ENABLED(Z_DUAL_ENDSTOPS) - #define _XMIN_ 100 - #define _YMIN_ 200 - #define _ZMIN_ 300 - #define _XMAX_ 101 - #define _YMAX_ 201 - #define _ZMAX_ 301 - #if Z2_USE_ENDSTOP == _XMIN_ - #define USE_XMIN_PLUG - #elif Z2_USE_ENDSTOP == _XMAX_ - #define USE_XMAX_PLUG - #elif Z2_USE_ENDSTOP == _YMIN_ - #define USE_YMIN_PLUG - #elif Z2_USE_ENDSTOP == _YMAX_ - #define USE_YMAX_PLUG - #elif Z2_USE_ENDSTOP == _ZMIN_ - #define USE_ZMIN_PLUG - #elif Z2_USE_ENDSTOP == _ZMAX_ - #define USE_ZMAX_PLUG - #endif #if Z_HOME_DIR > 0 #if Z2_USE_ENDSTOP == _XMIN_ #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING @@ -423,6 +516,7 @@ #else #define Z2_MAX_ENDSTOP_INVERTING false #endif + #define Z2_MIN_ENDSTOP_INVERTING false #else #if Z2_USE_ENDSTOP == _XMIN_ #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING @@ -445,6 +539,7 @@ #else #define Z2_MIN_ENDSTOP_INVERTING false #endif + #define Z2_MAX_ENDSTOP_INVERTING false #endif #endif @@ -541,12 +636,16 @@ #define HAS_SOLENOID_4 (PIN_EXISTS(SOL4)) // Endstops and bed probe - #define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_Z2_OR_PROBE(X,MIN)) - #define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_Z2_OR_PROBE(X,MAX)) - #define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_Z2_OR_PROBE(Y,MIN)) - #define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_Z2_OR_PROBE(Y,MAX)) - #define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_Z2_OR_PROBE(Z,MIN)) - #define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_Z2_OR_PROBE(Z,MAX)) + #define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_X2_ENDSTOP(X,MIN) && !IS_Y2_ENDSTOP(X,MIN) && !IS_Z2_OR_PROBE(X,MIN)) + #define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_X2_ENDSTOP(X,MAX) && !IS_Y2_ENDSTOP(X,MAX) && !IS_Z2_OR_PROBE(X,MAX)) + #define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_X2_ENDSTOP(Y,MIN) && !IS_Y2_ENDSTOP(Y,MIN) && !IS_Z2_OR_PROBE(Y,MIN)) + #define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_X2_ENDSTOP(Y,MAX) && !IS_Y2_ENDSTOP(Y,MAX) && !IS_Z2_OR_PROBE(Y,MAX)) + #define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_X2_ENDSTOP(Z,MIN) && !IS_Y2_ENDSTOP(Z,MIN) && !IS_Z2_OR_PROBE(Z,MIN)) + #define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_X2_ENDSTOP(Z,MAX) && !IS_Y2_ENDSTOP(Z,MAX) && !IS_Z2_OR_PROBE(Z,MAX)) + #define HAS_X2_MIN (PIN_EXISTS(X2_MIN)) + #define HAS_X2_MAX (PIN_EXISTS(X2_MAX)) + #define HAS_Y2_MIN (PIN_EXISTS(Y2_MIN)) + #define HAS_Y2_MAX (PIN_EXISTS(Y2_MAX)) #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN)) #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX)) #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE)) @@ -705,8 +804,7 @@ #endif #endif - #define PROBE_PIN_CONFIGURED (HAS_Z_MIN_PROBE_PIN || (HAS_Z_MIN && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN))) - #define HAS_BED_PROBE (PROBE_SELECTED && PROBE_PIN_CONFIGURED && DISABLED(PROBE_MANUALLY)) + #define HAS_BED_PROBE (PROBE_SELECTED && DISABLED(PROBE_MANUALLY)) #if ENABLED(Z_PROBE_ALLEN_KEY) #define PROBE_IS_TRIGGERED_WHEN_STOWED_TEST @@ -746,6 +844,49 @@ #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 #endif + /** + * XYZ Bed Skew Correction + */ + #if ENABLED(SKEW_CORRECTION) + #define SKEW_FACTOR_MIN -1 + #define SKEW_FACTOR_MAX 1 + + #define _GET_SIDE(a,b,c) (SQRT(2*sq(a)+2*sq(b)-4*sq(c))*0.5) + #define _SKEW_SIDE(a,b,c) tan(M_PI*0.5-acos((sq(a)-sq(b)-sq(c))/(2*c*b))) + #define _SKEW_FACTOR(a,b,c) _SKEW_SIDE(a,_GET_SIDE(a,b,c),c) + + #ifndef XY_SKEW_FACTOR + constexpr float XY_SKEW_FACTOR = ( + #if defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD) + _SKEW_FACTOR(XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD) + #else + 0.0 + #endif + ); + #endif + #ifndef XZ_SKEW_FACTOR + #if defined(XY_SIDE_AD) && !defined(XZ_SIDE_AD) + #define XZ_SIDE_AD XY_SIDE_AD + #endif + constexpr float XZ_SKEW_FACTOR = ( + #if defined(XZ_DIAG_AC) && defined(XZ_DIAG_BD) && defined(XZ_SIDE_AD) + _SKEW_FACTOR(XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD) + #else + 0.0 + #endif + ); + #endif + #ifndef YZ_SKEW_FACTOR + constexpr float YZ_SKEW_FACTOR = ( + #if defined(YZ_DIAG_AC) && defined(YZ_DIAG_BD) && defined(YZ_SIDE_AD) + _SKEW_FACTOR(YZ_DIAG_AC, YZ_DIAG_BD, YZ_SIDE_AD) + #else + 0.0 + #endif + ); + #endif + #endif // SKEW_CORRECTION + /** * Heater & Fan Pausing */ @@ -755,10 +896,23 @@ #define QUIET_PROBING (HAS_BED_PROBE && (ENABLED(PROBING_HEATERS_OFF) || ENABLED(PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0)) #define HEATER_IDLE_HANDLER (ENABLED(ADVANCED_PAUSE_FEATURE) || ENABLED(PROBING_HEATERS_OFF)) + /** + * Only constrain Z on DELTA / SCARA machines + */ + #if IS_KINEMATIC + #undef MIN_SOFTWARE_ENDSTOP_X + #undef MIN_SOFTWARE_ENDSTOP_Y + #undef MAX_SOFTWARE_ENDSTOP_X + #undef MAX_SOFTWARE_ENDSTOP_Y + #endif + /** * Delta radius/rod trimmers/angle trimmers */ #if ENABLED(DELTA) + #ifndef DELTA_PROBEABLE_RADIUS + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS + #endif #ifndef DELTA_CALIBRATION_RADIUS #define DELTA_CALIBRATION_RADIUS DELTA_PRINTABLE_RADIUS - 10 #endif @@ -779,19 +933,103 @@ /** * Set granular options based on the specific type of leveling */ - - #define UBL_DELTA (ENABLED(AUTO_BED_LEVELING_UBL) && (ENABLED(DELTA) || ENABLED(UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN))) - #define ABL_PLANAR (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_3POINT)) - #define ABL_GRID (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)) - #define HAS_ABL (ABL_PLANAR || ABL_GRID || ENABLED(AUTO_BED_LEVELING_UBL)) - #define HAS_LEVELING (HAS_ABL || ENABLED(MESH_BED_LEVELING)) - #define PLANNER_LEVELING (ABL_PLANAR || ABL_GRID || ENABLED(MESH_BED_LEVELING) || UBL_DELTA) + #define UBL_SEGMENTED (ENABLED(AUTO_BED_LEVELING_UBL) && (ENABLED(DELTA) || ENABLED(SEGMENT_LEVELED_MOVES))) + #define ABL_PLANAR (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_3POINT)) + #define ABL_GRID (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)) + #define OLDSCHOOL_ABL (ABL_PLANAR || ABL_GRID) + #define HAS_ABL (OLDSCHOOL_ABL || ENABLED(AUTO_BED_LEVELING_UBL)) + #define HAS_LEVELING (HAS_ABL || ENABLED(MESH_BED_LEVELING)) + #define HAS_AUTOLEVEL (HAS_ABL && DISABLED(PROBE_MANUALLY)) + #define HAS_MESH (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING)) + #define PLANNER_LEVELING (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_SEGMENTED || ENABLED(SKEW_CORRECTION)) #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)) #if HAS_PROBING_PROCEDURE #define PROBE_BED_WIDTH abs(RIGHT_PROBE_BED_POSITION - (LEFT_PROBE_BED_POSITION)) #define PROBE_BED_HEIGHT abs(BACK_PROBE_BED_POSITION - (FRONT_PROBE_BED_POSITION)) #endif + #if ENABLED(SEGMENT_LEVELED_MOVES) && !defined(LEVELED_SEGMENT_LENGTH) + #define LEVELED_SEGMENT_LENGTH 5 + #endif + + /** + * Bed Probing rectangular bounds + * These can be further constrained in code for Delta and SCARA + */ + #if ENABLED(DELTA) + // Probing points may be verified at compile time within the radius + // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!") + // so that may be added to SanityCheck.h in the future. + #define _MIN_PROBE_X (X_CENTER - DELTA_PRINTABLE_RADIUS) + #define _MIN_PROBE_Y (Y_CENTER - DELTA_PRINTABLE_RADIUS) + #define _MAX_PROBE_X (X_CENTER + DELTA_PRINTABLE_RADIUS) + #define _MAX_PROBE_Y (Y_CENTER + DELTA_PRINTABLE_RADIUS) + #elif IS_SCARA + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) + #define _MIN_PROBE_X (X_CENTER - (SCARA_PRINTABLE_RADIUS)) + #define _MIN_PROBE_Y (Y_CENTER - (SCARA_PRINTABLE_RADIUS)) + #define _MAX_PROBE_X (X_CENTER + SCARA_PRINTABLE_RADIUS) + #define _MAX_PROBE_Y (Y_CENTER + SCARA_PRINTABLE_RADIUS) + #else + // Boundaries for Cartesian probing based on bed limits + #define _MIN_PROBE_X (max(X_MIN_BED, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MIN_PROBE_Y (max(Y_MIN_BED, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MAX_PROBE_X (min(X_MAX_BED, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MAX_PROBE_Y (min(Y_MAX_BED, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #endif + + // Allow configuration to override these for special purposes + #ifndef MIN_PROBE_X + #define MIN_PROBE_X _MIN_PROBE_X + #endif + #ifndef MIN_PROBE_Y + #define MIN_PROBE_Y _MIN_PROBE_Y + #endif + #ifndef MAX_PROBE_X + #define MAX_PROBE_X _MAX_PROBE_X + #endif + #ifndef MAX_PROBE_Y + #define MAX_PROBE_Y _MAX_PROBE_Y + #endif + + /** + * Default mesh area is an area with an inset margin on the print area. + */ + #if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_UBL) + #if IS_KINEMATIC + // Probing points may be verified at compile time within the radius + // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!") + // so that may be added to SanityCheck.h in the future. + #define _MESH_MIN_X (MIN_PROBE_X + MESH_INSET) + #define _MESH_MIN_Y (MIN_PROBE_Y + MESH_INSET) + #define _MESH_MAX_X (MAX_PROBE_X - (MESH_INSET)) + #define _MESH_MAX_Y (MAX_PROBE_Y - (MESH_INSET)) + #else + // Boundaries for Cartesian probing based on set limits + #define _MESH_MIN_X (max(X_MIN_BED + MESH_INSET, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MESH_MIN_Y (max(Y_MIN_BED + MESH_INSET, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MESH_MAX_X (min(X_MAX_BED - (MESH_INSET), X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define _MESH_MAX_Y (min(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #endif + /** + * These may be overridden in Configuration if a smaller area is wanted + */ + #if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_UBL) + #ifndef MESH_MIN_X + #define MESH_MIN_X _MESH_MIN_X + #endif + #ifndef MESH_MIN_Y + #define MESH_MIN_Y _MESH_MIN_Y + #endif + #ifndef MESH_MAX_X + #define MESH_MAX_X _MESH_MAX_X + #endif + #ifndef MESH_MAX_Y + #define MESH_MAX_Y _MESH_MAX_Y + #endif + #endif + #endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL + /** * Buzzer/Speaker */ @@ -811,6 +1049,18 @@ #endif #endif + /** + * VIKI2, miniVIKI, and AZSMZ_12864 require DOGLCD_SCK and DOGLCD_MOSI to be defined. + */ + #if ENABLED(VIKI2) || ENABLED(miniVIKI) || ENABLED(AZSMZ_12864) + #ifndef DOGLCD_SCK + #define DOGLCD_SCK SCK_PIN + #endif + #ifndef DOGLCD_MOSI + #define DOGLCD_MOSI MOSI_PIN + #endif + #endif + /** * Z_HOMING_HEIGHT / Z_CLEARANCE_BETWEEN_PROBES */ @@ -830,42 +1080,6 @@ #define MANUAL_PROBE_HEIGHT Z_HOMING_HEIGHT #endif - /** - * Bed Probing rectangular bounds - * These can be further constrained in code for Delta and SCARA - */ - #if ENABLED(DELTA) - #ifndef DELTA_PROBEABLE_RADIUS - #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS - #endif - // Probing points may be verified at compile time within the radius - // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!") - // so that may be added to SanityCheck.h in the future. - #define MIN_PROBE_X (X_CENTER - (DELTA_PROBEABLE_RADIUS)) - #define MIN_PROBE_Y (Y_CENTER - (DELTA_PROBEABLE_RADIUS)) - #define MAX_PROBE_X (X_CENTER + DELTA_PROBEABLE_RADIUS) - #define MAX_PROBE_Y (Y_CENTER + DELTA_PROBEABLE_RADIUS) - #elif IS_SCARA - #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) - #define MIN_PROBE_X (X_CENTER - (SCARA_PRINTABLE_RADIUS)) - #define MIN_PROBE_Y (Y_CENTER - (SCARA_PRINTABLE_RADIUS)) - #define MAX_PROBE_X (X_CENTER + SCARA_PRINTABLE_RADIUS) - #define MAX_PROBE_Y (Y_CENTER + SCARA_PRINTABLE_RADIUS) - #else - // Boundaries for Cartesian probing based on set limits - #if ENABLED(BED_CENTER_AT_0_0) - #define MIN_PROBE_X (max(X_PROBE_OFFSET_FROM_EXTRUDER, 0) - (X_BED_SIZE) / 2) - #define MIN_PROBE_Y (max(Y_PROBE_OFFSET_FROM_EXTRUDER, 0) - (Y_BED_SIZE) / 2) - #define MAX_PROBE_X (min(X_BED_SIZE + X_PROBE_OFFSET_FROM_EXTRUDER, X_BED_SIZE) - (X_BED_SIZE) / 2) - #define MAX_PROBE_Y (min(Y_BED_SIZE + Y_PROBE_OFFSET_FROM_EXTRUDER, Y_BED_SIZE) - (Y_BED_SIZE) / 2) - #else - #define MIN_PROBE_X (max(X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER, 0)) - #define MIN_PROBE_Y (max(Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER, 0)) - #define MAX_PROBE_X (min(X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER, X_BED_SIZE)) - #define MAX_PROBE_Y (min(Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER, Y_BED_SIZE)) - #endif - #endif - // Stepper pulse duration, in cycles #define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND) @@ -876,7 +1090,7 @@ // Updated G92 behavior shifts the workspace #define HAS_POSITION_SHIFT DISABLED(NO_WORKSPACE_OFFSETS) // The home offset also shifts the coordinate space - #define HAS_HOME_OFFSET (DISABLED(NO_WORKSPACE_OFFSETS) || ENABLED(DELTA)) + #define HAS_HOME_OFFSET (DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)) // Either offset yields extra calculations on all moves #define HAS_WORKSPACE_OFFSET (HAS_POSITION_SHIFT || HAS_HOME_OFFSET) // M206 doesn't apply to DELTA @@ -887,31 +1101,11 @@ #define LCD_TIMEOUT_TO_STATUS 15000 #endif - /** - * DELTA_SEGMENT_MIN_LENGTH for UBL_DELTA - */ - #if UBL_DELTA - #ifndef DELTA_SEGMENT_MIN_LENGTH - #if IS_SCARA - #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm - #elif ENABLED(DELTA) - #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) - #else // CARTESIAN - #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation) - #endif - #endif - #endif - // Shorthand #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) // Add commands that need sub-codes to this list - #define USE_GCODE_SUBCODES ENABLED(G38_PROBE_TARGET) - - // MESH_BED_LEVELING overrides PROBE_MANUALLY - #if ENABLED(MESH_BED_LEVELING) - #undef PROBE_MANUALLY - #endif + #define USE_GCODE_SUBCODES ENABLED(G38_PROBE_TARGET) || ENABLED(CNC_COORDINATE_SYSTEMS) // Parking Extruder #if ENABLED(PARKING_EXTRUDER) @@ -923,4 +1117,34 @@ #endif #endif + // Number of VFAT entries used. Each entry has 13 UTF-16 characters + #if ENABLED(SCROLL_LONG_FILENAMES) + #define MAX_VFAT_ENTRIES (5) + #else + #define MAX_VFAT_ENTRIES (2) + #endif + + // Set defaults for unspecified LED user colors + #if ENABLED(LED_CONTROL_MENU) + #ifndef LED_USER_PRESET_RED + #define LED_USER_PRESET_RED 255 + #endif + #ifndef LED_USER_PRESET_GREEN + #define LED_USER_PRESET_GREEN 255 + #endif + #ifndef LED_USER_PRESET_BLUE + #define LED_USER_PRESET_BLUE 255 + #endif + #ifndef LED_USER_PRESET_WHITE + #define LED_USER_PRESET_WHITE 0 + #endif + #ifndef LED_USER_PRESET_BRIGHTNESS + #ifdef NEOPIXEL_BRIGHTNESS + #define LED_USER_PRESET_BRIGHTNESS NEOPIXEL_BRIGHTNESS + #else + #define LED_USER_PRESET_BRIGHTNESS 255 + #endif + #endif + #endif + #endif // CONDITIONALS_POST_H diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 8fd17498b7..0b036f39c1 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1525,12 +1625,19 @@ //#define CR10_STOCKDISPLAY // -// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// MKS OLED 1.3" 128x64 FULL GRAPHICS CONTROLLER // http://reprap.org/wiki/MKS_12864OLED // // Tiny, but very sharp OLED display +// If there is a pixel shift, try the other controller. // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1695,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1721,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1637,18 +1744,18 @@ #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1768,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 3ed2a44b30..7d4b8896b4 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp index 92c86b7ff2..7c34b88136 100644 --- a/Marlin/G26_Mesh_Validation_Tool.cpp +++ b/Marlin/G26_Mesh_Validation_Tool.cpp @@ -26,24 +26,25 @@ #include "MarlinConfig.h" -#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) +#if ENABLED(G26_MESH_VALIDATION) - #include "ubl.h" #include "Marlin.h" #include "planner.h" #include "stepper.h" #include "temperature.h" #include "ultralcd.h" #include "gcode.h" + #include "bitmap_flags.h" + + #if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" + #elif ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" + #endif #define EXTRUSION_MULTIPLIER 1.0 #define RETRACTION_MULTIPLIER 1.0 - #define NOZZLE 0.4 - #define FILAMENT 1.75 - #define LAYER_HEIGHT 0.2 #define PRIME_LENGTH 10.0 - #define BED_TEMP 60.0 - #define HOTEND_TEMP 205.0 #define OOZE_AMOUNT 0.3 #define SIZE_OF_INTERSECTION_CIRCLES 5 @@ -53,6 +54,9 @@ #error "SIZE_OF_CROSSHAIRS must be less than SIZE_OF_INTERSECTION_CIRCLES." #endif + #define G26_OK false + #define G26_ERR true + /** * G26 Mesh Validation Tool * @@ -128,20 +132,11 @@ // External references - extern float feedrate_mm_s; // must set before calling prepare_move_to_destination extern Planner planner; #if ENABLED(ULTRA_LCD) extern char lcd_status_message[]; #endif - extern float destination[XYZE]; - void set_destination_to_current(); - void prepare_move_to_destination(); inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); } - inline void set_current_to_destination() { COPY(current_position, destination); } - #if ENABLED(NEWPANEL) - void lcd_setstatusPGM(const char* const message, const int8_t level); - void chirp_at_user(); - #endif // Private functions @@ -152,67 +147,404 @@ static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched // retracts/recovers won't result in a bad state. - float valid_trig_angle(float); + static float g26_extrusion_multiplier, + g26_retraction_multiplier, + g26_layer_height, + g26_prime_length, + g26_x_pos, g26_y_pos; - float unified_bed_leveling::g26_extrusion_multiplier, - unified_bed_leveling::g26_retraction_multiplier, - unified_bed_leveling::g26_nozzle, - unified_bed_leveling::g26_filament_diameter, - unified_bed_leveling::g26_layer_height, - unified_bed_leveling::g26_prime_length, - unified_bed_leveling::g26_x_pos, - unified_bed_leveling::g26_y_pos, - unified_bed_leveling::g26_ooze_amount; + static int16_t g26_bed_temp, + g26_hotend_temp; - int16_t unified_bed_leveling::g26_bed_temp, - unified_bed_leveling::g26_hotend_temp; + static int8_t g26_prime_flag; - int8_t unified_bed_leveling::g26_prime_flag; + #if ENABLED(NEWPANEL) - bool unified_bed_leveling::g26_continue_with_closest, - unified_bed_leveling::g26_keep_heaters_on; + /** + * If the LCD is clicked, cancel, wait for release, return true + */ + bool user_canceled() { + if (!is_lcd_clicked()) return false; // Return if the button isn't pressed + lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); + #if ENABLED(ULTIPANEL) + lcd_quick_feedback(); + #endif + wait_for_release(); + return true; + } - int16_t unified_bed_leveling::g26_repeats; + bool exit_from_g26() { + lcd_setstatusPGM(PSTR("Leaving G26"), -1); + wait_for_release(); + return G26_ERR; + } - void unified_bed_leveling::G26_line_to_destination(const float &feed_rate) { + #endif + + void G26_line_to_destination(const float &feed_rate) { const float save_feedrate = feedrate_mm_s; feedrate_mm_s = feed_rate; // use specified feed rate - prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA + prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_SEGMENTED feedrate_mm_s = save_feedrate; // restore global feed rate } - #if ENABLED(NEWPANEL) - /** - * Detect ubl_lcd_clicked, debounce it, and return true for cancel - */ - bool user_canceled() { - if (!ubl_lcd_clicked()) return false; - safe_delay(10); // Wait for click to settle + void move_to(const float &rx, const float &ry, const float &z, const float &e_delta) { + float feed_value; + static float last_z = -999.99; + bool has_xy_component = (rx != current_position[X_AXIS] || ry != current_position[Y_AXIS]); // Check if X or Y is involved in the movement. + + if (z != last_z) { + last_z = z; + feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate + + destination[X_AXIS] = current_position[X_AXIS]; + destination[Y_AXIS] = current_position[Y_AXIS]; + destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code. + destination[E_AXIS] = current_position[E_AXIS]; + + G26_line_to_destination(feed_value); + + stepper.synchronize(); + set_destination_from_current(); + } + + // Check if X or Y is involved in the movement. + // Yes: a 'normal' movement. No: a retract() or recover() + feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5; + + if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value); + + destination[X_AXIS] = rx; + destination[Y_AXIS] = ry; + destination[E_AXIS] += e_delta; + + G26_line_to_destination(feed_value); + + stepper.synchronize(); + set_destination_from_current(); + } + + FORCE_INLINE void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); } + + void retract_filament(const float where[XYZE]) { + if (!g26_retracted) { // Only retract if we are not already retracted! + g26_retracted = true; + move_to(where, -1.0 * g26_retraction_multiplier); + } + } + + void recover_filament(const float where[XYZE]) { + if (g26_retracted) { // Only un-retract if we are retracted. + move_to(where, 1.2 * g26_retraction_multiplier); + g26_retracted = false; + } + } + + /** + * Prime the nozzle if needed. Return true on error. + */ + inline bool prime_nozzle() { + + #if ENABLED(NEWPANEL) + float Total_Prime = 0.0; + + if (g26_prime_flag == -1) { // The user wants to control how much filament gets purged + + lcd_external_control = true; + lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99); + lcd_chirp(); + + set_destination_from_current(); + + recover_filament(destination); // Make sure G26 doesn't think the filament is retracted(). + + while (!is_lcd_clicked()) { + lcd_chirp(); + destination[E_AXIS] += 0.25; + #ifdef PREVENT_LENGTHY_EXTRUDE + Total_Prime += 0.25; + if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR; + #endif + G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); + + stepper.synchronize(); // Without this synchronize, the purge is more consistent, + // but because the planner has a buffer, we won't be able + // to stop as quickly. So we put up with the less smooth + // action to give the user a more responsive 'Stop'. + set_destination_from_current(); + idle(); + } + + wait_for_release(); + + strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; + // So... We cheat to get a message up. + lcd_setstatusPGM(PSTR("Done Priming"), 99); + lcd_quick_feedback(); + lcd_external_control = false; + } + else + #endif + { #if ENABLED(ULTRA_LCD) - lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); + lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); lcd_quick_feedback(); #endif - - while (!ubl_lcd_clicked()) idle(); // Wait for button release - - // If the button is suddenly pressed again, - // ask the user to resolve the issue - lcd_setstatusPGM(PSTR("Release button"), 99); // will never appear... - while (ubl_lcd_clicked()) idle(); // unless this loop happens - lcd_reset_status(); - - return true; + set_destination_from_current(); + destination[E_AXIS] += g26_prime_length; + G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); + stepper.synchronize(); + set_destination_from_current(); + retract_filament(destination); } - #endif + + return G26_OK; + } + + mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) { + float closest = 99999.99; + mesh_index_pair return_val; + + return_val.x_index = return_val.y_index = -1; + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + if (!is_bitmap_set(circle_flags, i, j)) { + const float mx = _GET_MESH_X(i), // We found a circle that needs to be printed + my = _GET_MESH_Y(j); + + // Get the distance to this intersection + float f = HYPOT(X - mx, Y - my); + + // It is possible that we are being called with the values + // to let us find the closest circle to the start position. + // But if this is not the case, add a small weighting to the + // distance calculation to help it choose a better place to continue. + f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0; + + // Add in the specified amount of Random Noise to our search + if (random_deviation > 1.0) + f += random(0.0, random_deviation); + + if (f < closest) { + closest = f; // We found a closer location that is still + return_val.x_index = i; // un-printed --- save the data for it + return_val.y_index = j; + return_val.distance = closest; + } + } + } + } + bitmap_set(circle_flags, return_val.x_index, return_val.y_index); // Mark this location as done. + return return_val; + } + + /** + * print_line_from_here_to_there() takes two cartesian coordinates and draws a line from one + * to the other. But there are really three sets of coordinates involved. The first coordinate + * is the present location of the nozzle. We don't necessarily want to print from this location. + * We first need to move the nozzle to the start of line segment where we want to print. Once + * there, we can use the two coordinates supplied to draw the line. + * + * Note: Although we assume the first set of coordinates is the start of the line and the second + * set of coordinates is the end of the line, it does not always work out that way. This function + * optimizes the movement to minimize the travel distance before it can start printing. This saves + * a lot of time and eliminates a lot of nonsensical movement of the nozzle. However, it does + * cause a lot of very little short retracement of th nozzle when it draws the very first line + * segment of a 'circle'. The time this requires is very short and is easily saved by the other + * cases where the optimization comes into play. + */ + void print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) { + const float dx_s = current_position[X_AXIS] - sx, // find our distance from the start of the actual line segment + dy_s = current_position[Y_AXIS] - sy, + dist_start = HYPOT2(dx_s, dy_s), // We don't need to do a sqrt(), we can compare the distance^2 + // to save computation time + dx_e = current_position[X_AXIS] - ex, // find our distance from the end of the actual line segment + dy_e = current_position[Y_AXIS] - ey, + dist_end = HYPOT2(dx_e, dy_e), + + line_length = HYPOT(ex - sx, ey - sy); + + // If the end point of the line is closer to the nozzle, flip the direction, + // moving from the end to the start. On very small lines the optimization isn't worth it. + if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length)) + return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz); + + // Decide whether to retract & bump + + if (dist_start > 2.0) { + retract_filament(destination); + //todo: parameterize the bump height with a define + move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0); // Z bump to minimize scraping + move_to(sx, sy, sz + 0.500, 0.0); // Get to the starting point with no extrusion while bumped + } + + move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump + + const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier; + + recover_filament(destination); + move_to(ex, ey, ez, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion + } + + inline bool look_for_lines_to_connect() { + float sx, sy, ex, ey; + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + + #if ENABLED(NEWPANEL) + if (user_canceled()) return true; // Check if the user wants to stop the Mesh Validation + #endif + + if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X. + // This is already a half circle because we are at the edge of the bed. + + if (is_bitmap_set(circle_flags, i, j) && is_bitmap_set(circle_flags, i + 1, j)) { // check if we can do a line to the left + if (!is_bitmap_set(horizontal_mesh_line_flags, i, j)) { + + // + // We found two circles that need a horizontal line to connect them + // Print it! + // + sx = _GET_MESH_X( i ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge + ex = _GET_MESH_X(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge + + sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1); + sy = ey = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1); + ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1); + + if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) { + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx); + SERIAL_ECHOPAIR(", sy=", sy); + SERIAL_ECHOPAIR(") -> (ex=", ex); + SERIAL_ECHOPAIR(", ey=", ey); + SERIAL_CHAR(')'); + SERIAL_EOL(); + //debug_current_and_destination(PSTR("Connecting horizontal line.")); + } + print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height); + } + bitmap_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it + } + } + + if (j < GRID_MAX_POINTS_Y) { // We can't connect to anything further back than GRID_MAX_POINTS_Y. + // This is already a half circle because we are at the edge of the bed. + + if (is_bitmap_set(circle_flags, i, j) && is_bitmap_set(circle_flags, i, j + 1)) { // check if we can do a line straight down + if (!is_bitmap_set( vertical_mesh_line_flags, i, j)) { + // + // We found two circles that need a vertical line to connect them + // Print it! + // + sy = _GET_MESH_Y( j ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge + ey = _GET_MESH_Y(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge + + sx = ex = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1); + sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1); + ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1); + + if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) { + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx); + SERIAL_ECHOPAIR(", sy=", sy); + SERIAL_ECHOPAIR(") -> (ex=", ex); + SERIAL_ECHOPAIR(", ey=", ey); + SERIAL_CHAR(')'); + SERIAL_EOL(); + + #if ENABLED(AUTO_BED_LEVELING_UBL) + debug_current_and_destination(PSTR("Connecting vertical line.")); + #endif + } + print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height); + } + bitmap_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped + } + } + } + } + } + } + return false; + } + + /** + * Turn on the bed and nozzle heat and + * wait for them to get up to temperature. + */ + inline bool turn_on_heaters() { + millis_t next = millis() + 5000UL; + #if HAS_TEMP_BED + #if ENABLED(ULTRA_LCD) + if (g26_bed_temp > 25) { + lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); + lcd_quick_feedback(); + lcd_external_control = true; + #endif + thermalManager.setTargetBed(g26_bed_temp); + while (abs(thermalManager.degBed() - g26_bed_temp) > 3) { + + #if ENABLED(NEWPANEL) + if (is_lcd_clicked()) return exit_from_g26(); + #endif + + if (ELAPSED(millis(), next)) { + next = millis() + 5000UL; + thermalManager.print_heaterstates(); + SERIAL_EOL(); + } + idle(); + } + #if ENABLED(ULTRA_LCD) + } + lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99); + lcd_quick_feedback(); + #endif + #endif + + // Start heating the nozzle and wait for it to reach temperature. + thermalManager.setTargetHotend(g26_hotend_temp, 0); + while (abs(thermalManager.degHotend(0) - g26_hotend_temp) > 3) { + + #if ENABLED(NEWPANEL) + if (is_lcd_clicked()) return exit_from_g26(); + #endif + + if (ELAPSED(millis(), next)) { + next = millis() + 5000UL; + thermalManager.print_heaterstates(); + SERIAL_EOL(); + } + idle(); + } + + #if ENABLED(ULTRA_LCD) + lcd_reset_status(); + lcd_quick_feedback(); + #endif + + return G26_OK; + } + + float valid_trig_angle(float d) { + while (d > 360.0) d -= 360.0; + while (d < 0.0) d += 360.0; + return d; + } /** * G26: Mesh Validation Pattern generation. * - * Used to interactively edit UBL's Mesh by placing the + * Used to interactively edit the mesh by placing the * nozzle in a problem area and doing a G29 P4 R command. */ - void unified_bed_leveling::G26() { + void gcode_G26() { SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s)."); float tmp, start_angle, end_angle; int i, xi, yi; @@ -220,20 +552,147 @@ // Don't allow Mesh Validation without homing first, // or if the parameter parsing did not go OK, abort - if (axis_unhomed_error() || parse_G26_parameters()) return; + if (axis_unhomed_error()) return; + + g26_extrusion_multiplier = EXTRUSION_MULTIPLIER; + g26_retraction_multiplier = RETRACTION_MULTIPLIER; + g26_layer_height = MESH_TEST_LAYER_HEIGHT; + g26_prime_length = PRIME_LENGTH; + g26_bed_temp = MESH_TEST_BED_TEMP; + g26_hotend_temp = MESH_TEST_HOTEND_TEMP; + g26_prime_flag = 0; + + float g26_nozzle = MESH_TEST_NOZZLE_SIZE, + g26_filament_diameter = DEFAULT_NOMINAL_FILAMENT_DIA, + g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT); + + bool g26_continue_with_closest = parser.boolval('C'), + g26_keep_heaters_on = parser.boolval('K'); + + if (parser.seenval('B')) { + g26_bed_temp = parser.value_celsius(); + if (!WITHIN(g26_bed_temp, 15, 140)) { + SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible."); + return; + } + } + + if (parser.seenval('L')) { + g26_layer_height = parser.value_linear_units(); + if (!WITHIN(g26_layer_height, 0.0, 2.0)) { + SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible."); + return; + } + } + + if (parser.seen('Q')) { + if (parser.has_value()) { + g26_retraction_multiplier = parser.value_float(); + if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) { + SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible."); + return; + } + } + else { + SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified."); + return; + } + } + + if (parser.seenval('S')) { + g26_nozzle = parser.value_float(); + if (!WITHIN(g26_nozzle, 0.1, 1.0)) { + SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible."); + return; + } + } + + if (parser.seen('P')) { + if (!parser.has_value()) { + #if ENABLED(NEWPANEL) + g26_prime_flag = -1; + #else + SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD."); + return; + #endif + } + else { + g26_prime_flag++; + g26_prime_length = parser.value_linear_units(); + if (!WITHIN(g26_prime_length, 0.0, 25.0)) { + SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible."); + return; + } + } + } + + if (parser.seenval('F')) { + g26_filament_diameter = parser.value_linear_units(); + if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) { + SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible."); + return; + } + } + g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to + // scale up or down the length needed to get the + // same volume of filament + + g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size + + if (parser.seenval('H')) { + g26_hotend_temp = parser.value_celsius(); + if (!WITHIN(g26_hotend_temp, 165, 280)) { + SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible."); + return; + } + } + + if (parser.seen('U')) { + randomSeed(millis()); + // This setting will persist for the next G26 + random_deviation = parser.has_value() ? parser.value_float() : 50.0; + } + + int16_t g26_repeats; + #if ENABLED(NEWPANEL) + g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); + #else + if (!parser.seen('R')) { + SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD."); + return; + } + else + g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; + #endif + if (g26_repeats < 1) { + SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1."); + return; + } + + g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS]; + g26_y_pos = parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position[Y_AXIS]; + if (!position_is_reachable(g26_x_pos, g26_y_pos)) { + SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); + return; + } + + /** + * Wait until all parameters are verified before altering the state! + */ + set_bed_leveling_enabled(!parser.seen('D')); if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) { do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); stepper.synchronize(); - set_current_to_destination(); + set_current_from_destination(); } - if (turn_on_heaters()) goto LEAVE; + if (turn_on_heaters() != G26_OK) goto LEAVE; current_position[E_AXIS] = 0.0; sync_plan_position_e(); - if (g26_prime_flag && prime_nozzle()) goto LEAVE; + if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE; /** * Bed is preheated @@ -250,12 +709,15 @@ ZERO(vertical_mesh_line_flags); // Move nozzle to the specified height for the first layer - set_destination_to_current(); + set_destination_from_current(); destination[Z_AXIS] = g26_layer_height; move_to(destination, 0.0); move_to(destination, g26_ooze_amount); - has_control_of_lcd_panel = true; + #if ENABLED(ULTRA_LCD) + lcd_external_control = true; + #endif + //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern.")); /** @@ -274,12 +736,12 @@ : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now. if (location.x_index >= 0 && location.y_index >= 0) { - const float circle_x = mesh_index_to_xpos(location.x_index), - circle_y = mesh_index_to_ypos(location.y_index); + const float circle_x = _GET_MESH_X(location.x_index), + circle_y = _GET_MESH_Y(location.y_index); // If this mesh location is outside the printable_radius, skip it. - if (!position_is_reachable_raw_xy(circle_x, circle_y)) continue; + if (!position_is_reachable(circle_x, circle_y)) continue; xi = location.x_index; // Just to shrink the next few lines and make them easier to understand yi = location.y_index; @@ -328,16 +790,16 @@ if (tmp_div_30 < 0) tmp_div_30 += 360 / 30; if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30; - float x = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry - y = circle_y + sin_table[tmp_div_30], + float rx = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry + ry = circle_y + sin_table[tmp_div_30], xe = circle_x + cos_table[tmp_div_30 + 1], ye = circle_y + sin_table[tmp_div_30 + 1]; #if IS_KINEMATIC // Check to make sure this segment is entirely on the bed, skip if not. - if (!position_is_reachable_raw_xy(x, y) || !position_is_reachable_raw_xy(xe, ye)) continue; - #else // not, we need to skip - x = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops - y = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1); + if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue; + #else // not, we need to skip + rx = constrain(rx, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops + ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1); xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1); ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1); #endif @@ -353,7 +815,7 @@ // debug_current_and_destination(seg_msg); //} - print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), g26_layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), g26_layer_height); + print_line_from_here_to_there(rx, ry, g26_layer_height, xe, ye, g26_layer_height); } if (look_for_lines_to_connect()) @@ -371,14 +833,16 @@ move_to(destination, 0); // Raise the nozzle //debug_current_and_destination(PSTR("done doing Z-Raise.")); - destination[X_AXIS] = g26_x_pos; // Move back to the starting position + destination[X_AXIS] = g26_x_pos; // Move back to the starting position destination[Y_AXIS] = g26_y_pos; - //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; // Keep the nozzle where it is + //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; // Keep the nozzle where it is move_to(destination, 0); // Move back to the starting position //debug_current_and_destination(PSTR("done doing X/Y move.")); - has_control_of_lcd_panel = false; // Give back control of the LCD Panel! + #if ENABLED(ULTRA_LCD) + lcd_external_control = false; // Give back control of the LCD Panel! + #endif if (!g26_keep_heaters_on) { #if HAS_TEMP_BED @@ -388,500 +852,4 @@ } } - float valid_trig_angle(float d) { - while (d > 360.0) d -= 360.0; - while (d < 0.0) d += 360.0; - return d; - } - - mesh_index_pair unified_bed_leveling::find_closest_circle_to_print(const float &X, const float &Y) { - float closest = 99999.99; - mesh_index_pair return_val; - - return_val.x_index = return_val.y_index = -1; - - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - if (!is_bit_set(circle_flags, i, j)) { - const float mx = mesh_index_to_xpos(i), // We found a circle that needs to be printed - my = mesh_index_to_ypos(j); - - // Get the distance to this intersection - float f = HYPOT(X - mx, Y - my); - - // It is possible that we are being called with the values - // to let us find the closest circle to the start position. - // But if this is not the case, add a small weighting to the - // distance calculation to help it choose a better place to continue. - f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0; - - // Add in the specified amount of Random Noise to our search - if (random_deviation > 1.0) - f += random(0.0, random_deviation); - - if (f < closest) { - closest = f; // We found a closer location that is still - return_val.x_index = i; // un-printed --- save the data for it - return_val.y_index = j; - return_val.distance = closest; - } - } - } - } - bit_set(circle_flags, return_val.x_index, return_val.y_index); // Mark this location as done. - return return_val; - } - - bool unified_bed_leveling::look_for_lines_to_connect() { - float sx, sy, ex, ey; - - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - - #if ENABLED(NEWPANEL) - if (user_canceled()) return true; // Check if the user wants to stop the Mesh Validation - #endif - - if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X. - // This is already a half circle because we are at the edge of the bed. - - if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i + 1, j)) { // check if we can do a line to the left - if (!is_bit_set(horizontal_mesh_line_flags, i, j)) { - - // - // We found two circles that need a horizontal line to connect them - // Print it! - // - sx = mesh_index_to_xpos( i ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge - ex = mesh_index_to_xpos(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge - - sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1); - sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1); - ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1); - - if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) { - - if (g26_debug_flag) { - SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx); - SERIAL_ECHOPAIR(", sy=", sy); - SERIAL_ECHOPAIR(") -> (ex=", ex); - SERIAL_ECHOPAIR(", ey=", ey); - SERIAL_CHAR(')'); - SERIAL_EOL(); - //debug_current_and_destination(PSTR("Connecting horizontal line.")); - } - - print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height); - } - bit_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it - } - } - - if (j < GRID_MAX_POINTS_Y) { // We can't connect to anything further back than GRID_MAX_POINTS_Y. - // This is already a half circle because we are at the edge of the bed. - - if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i, j + 1)) { // check if we can do a line straight down - if (!is_bit_set( vertical_mesh_line_flags, i, j)) { - // - // We found two circles that need a vertical line to connect them - // Print it! - // - sy = mesh_index_to_ypos( j ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge - ey = mesh_index_to_ypos(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge - - sx = ex = constrain(mesh_index_to_xpos(i), X_MIN_POS + 1, X_MAX_POS - 1); - sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1); - ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1); - - if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) { - - if (g26_debug_flag) { - SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx); - SERIAL_ECHOPAIR(", sy=", sy); - SERIAL_ECHOPAIR(") -> (ex=", ex); - SERIAL_ECHOPAIR(", ey=", ey); - SERIAL_CHAR(')'); - SERIAL_EOL(); - debug_current_and_destination(PSTR("Connecting vertical line.")); - } - print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height); - } - bit_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped - } - } - } - } - } - } - return false; - } - - void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) { - float feed_value; - static float last_z = -999.99; - - bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement. - - if (z != last_z) { - last_z = z; - feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate - - destination[X_AXIS] = current_position[X_AXIS]; - destination[Y_AXIS] = current_position[Y_AXIS]; - destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code. - destination[E_AXIS] = current_position[E_AXIS]; - - G26_line_to_destination(feed_value); - - stepper.synchronize(); - set_destination_to_current(); - } - - // Check if X or Y is involved in the movement. - // Yes: a 'normal' movement. No: a retract() or recover() - feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5; - - if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value); - - destination[X_AXIS] = x; - destination[Y_AXIS] = y; - destination[E_AXIS] += e_delta; - - G26_line_to_destination(feed_value); - - stepper.synchronize(); - set_destination_to_current(); - - } - - void unified_bed_leveling::retract_filament(const float where[XYZE]) { - if (!g26_retracted) { // Only retract if we are not already retracted! - g26_retracted = true; - move_to(where, -1.0 * g26_retraction_multiplier); - } - } - - void unified_bed_leveling::recover_filament(const float where[XYZE]) { - if (g26_retracted) { // Only un-retract if we are retracted. - move_to(where, 1.2 * g26_retraction_multiplier); - g26_retracted = false; - } - } - - /** - * print_line_from_here_to_there() takes two cartesian coordinates and draws a line from one - * to the other. But there are really three sets of coordinates involved. The first coordinate - * is the present location of the nozzle. We don't necessarily want to print from this location. - * We first need to move the nozzle to the start of line segment where we want to print. Once - * there, we can use the two coordinates supplied to draw the line. - * - * Note: Although we assume the first set of coordinates is the start of the line and the second - * set of coordinates is the end of the line, it does not always work out that way. This function - * optimizes the movement to minimize the travel distance before it can start printing. This saves - * a lot of time and eliminates a lot of nonsensical movement of the nozzle. However, it does - * cause a lot of very little short retracement of th nozzle when it draws the very first line - * segment of a 'circle'. The time this requires is very short and is easily saved by the other - * cases where the optimization comes into play. - */ - void unified_bed_leveling::print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) { - const float dx_s = current_position[X_AXIS] - sx, // find our distance from the start of the actual line segment - dy_s = current_position[Y_AXIS] - sy, - dist_start = HYPOT2(dx_s, dy_s), // We don't need to do a sqrt(), we can compare the distance^2 - // to save computation time - dx_e = current_position[X_AXIS] - ex, // find our distance from the end of the actual line segment - dy_e = current_position[Y_AXIS] - ey, - dist_end = HYPOT2(dx_e, dy_e), - - line_length = HYPOT(ex - sx, ey - sy); - - // If the end point of the line is closer to the nozzle, flip the direction, - // moving from the end to the start. On very small lines the optimization isn't worth it. - if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length)) { - return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz); - } - - // Decide whether to retract & bump - - if (dist_start > 2.0) { - retract_filament(destination); - //todo: parameterize the bump height with a define - move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0); // Z bump to minimize scraping - move_to(sx, sy, sz + 0.500, 0.0); // Get to the starting point with no extrusion while bumped - } - - move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump - - const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier; - - recover_filament(destination); - move_to(ex, ey, ez, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion - } - - /** - * This function used to be inline code in G26. But there are so many - * parameters it made sense to turn them into static globals and get - * this code out of sight of the main routine. - */ - bool unified_bed_leveling::parse_G26_parameters() { - - g26_extrusion_multiplier = EXTRUSION_MULTIPLIER; - g26_retraction_multiplier = RETRACTION_MULTIPLIER; - g26_nozzle = NOZZLE; - g26_filament_diameter = FILAMENT; - g26_layer_height = LAYER_HEIGHT; - g26_prime_length = PRIME_LENGTH; - g26_bed_temp = BED_TEMP; - g26_hotend_temp = HOTEND_TEMP; - g26_prime_flag = 0; - - g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT); - g26_keep_heaters_on = parser.boolval('K'); - g26_continue_with_closest = parser.boolval('C'); - - if (parser.seenval('B')) { - g26_bed_temp = parser.value_celsius(); - if (!WITHIN(g26_bed_temp, 15, 140)) { - SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible."); - return UBL_ERR; - } - } - - if (parser.seenval('L')) { - g26_layer_height = parser.value_linear_units(); - if (!WITHIN(g26_layer_height, 0.0, 2.0)) { - SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible."); - return UBL_ERR; - } - } - - if (parser.seen('Q')) { - if (parser.has_value()) { - g26_retraction_multiplier = parser.value_float(); - if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) { - SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible."); - return UBL_ERR; - } - } - else { - SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified."); - return UBL_ERR; - } - } - - if (parser.seenval('S')) { - g26_nozzle = parser.value_float(); - if (!WITHIN(g26_nozzle, 0.1, 1.0)) { - SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible."); - return UBL_ERR; - } - } - - if (parser.seen('P')) { - if (!parser.has_value()) { - #if ENABLED(NEWPANEL) - g26_prime_flag = -1; - #else - SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD."); - return UBL_ERR; - #endif - } - else { - g26_prime_flag++; - g26_prime_length = parser.value_linear_units(); - if (!WITHIN(g26_prime_length, 0.0, 25.0)) { - SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible."); - return UBL_ERR; - } - } - } - - if (parser.seenval('F')) { - g26_filament_diameter = parser.value_linear_units(); - if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) { - SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible."); - return UBL_ERR; - } - } - g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to - // scale up or down the length needed to get the - // same volume of filament - - g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size - - if (parser.seenval('H')) { - g26_hotend_temp = parser.value_celsius(); - if (!WITHIN(g26_hotend_temp, 165, 280)) { - SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible."); - return UBL_ERR; - } - } - - if (parser.seen('U')) { - randomSeed(millis()); - // This setting will persist for the next G26 - random_deviation = parser.has_value() ? parser.value_float() : 50.0; - } - - #if ENABLED(NEWPANEL) - g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); - #else - if (!parser.seen('R')) { - SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD."); - return UBL_ERR; - } - else - g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; - #endif - if (g26_repeats < 1) { - SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1."); - return UBL_ERR; - } - - g26_x_pos = parser.linearval('X', current_position[X_AXIS]); - g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]); - if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) { - SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); - return UBL_ERR; - } - - /** - * Wait until all parameters are verified before altering the state! - */ - set_bed_leveling_enabled(!parser.seen('D')); - - return UBL_OK; - } - - #if ENABLED(NEWPANEL) - bool unified_bed_leveling::exit_from_g26() { - lcd_setstatusPGM(PSTR("Leaving G26"), -1); - while (ubl_lcd_clicked()) idle(); - return UBL_ERR; - } - #endif - - /** - * Turn on the bed and nozzle heat and - * wait for them to get up to temperature. - */ - bool unified_bed_leveling::turn_on_heaters() { - millis_t next = millis() + 5000UL; - #if HAS_TEMP_BED - #if ENABLED(ULTRA_LCD) - if (g26_bed_temp > 25) { - lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); - lcd_quick_feedback(); - #endif - has_control_of_lcd_panel = true; - thermalManager.setTargetBed(g26_bed_temp); - while (abs(thermalManager.degBed() - g26_bed_temp) > 3) { - - #if ENABLED(NEWPANEL) - if (ubl_lcd_clicked()) return exit_from_g26(); - #endif - - if (ELAPSED(millis(), next)) { - next = millis() + 5000UL; - print_heaterstates(); - SERIAL_EOL(); - } - idle(); - } - #if ENABLED(ULTRA_LCD) - } - lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99); - lcd_quick_feedback(); - #endif - #endif - - // Start heating the nozzle and wait for it to reach temperature. - thermalManager.setTargetHotend(g26_hotend_temp, 0); - while (abs(thermalManager.degHotend(0) - g26_hotend_temp) > 3) { - - #if ENABLED(NEWPANEL) - if (ubl_lcd_clicked()) return exit_from_g26(); - #endif - - if (ELAPSED(millis(), next)) { - next = millis() + 5000UL; - print_heaterstates(); - SERIAL_EOL(); - } - idle(); - } - - #if ENABLED(ULTRA_LCD) - lcd_reset_status(); - lcd_quick_feedback(); - #endif - - return UBL_OK; - } - - /** - * Prime the nozzle if needed. Return true on error. - */ - bool unified_bed_leveling::prime_nozzle() { - - #if ENABLED(NEWPANEL) - float Total_Prime = 0.0; - - if (g26_prime_flag == -1) { // The user wants to control how much filament gets purged - - has_control_of_lcd_panel = true; - lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99); - chirp_at_user(); - - set_destination_to_current(); - - recover_filament(destination); // Make sure G26 doesn't think the filament is retracted(). - - while (!ubl_lcd_clicked()) { - chirp_at_user(); - destination[E_AXIS] += 0.25; - #ifdef PREVENT_LENGTHY_EXTRUDE - Total_Prime += 0.25; - if (Total_Prime >= EXTRUDE_MAXLENGTH) return UBL_ERR; - #endif - G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); - - stepper.synchronize(); // Without this synchronize, the purge is more consistent, - // but because the planner has a buffer, we won't be able - // to stop as quickly. So we put up with the less smooth - // action to give the user a more responsive 'Stop'. - set_destination_to_current(); - idle(); - } - - while (ubl_lcd_clicked()) idle(); // Debounce Encoder Wheel - - #if ENABLED(ULTRA_LCD) - strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; - // So... We cheat to get a message up. - lcd_setstatusPGM(PSTR("Done Priming"), 99); - lcd_quick_feedback(); - #endif - - has_control_of_lcd_panel = false; - - } - else { - #else - { - #endif - #if ENABLED(ULTRA_LCD) - lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); - lcd_quick_feedback(); - #endif - set_destination_to_current(); - destination[E_AXIS] += g26_prime_length; - G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); - stepper.synchronize(); - set_destination_to_current(); - retract_filament(destination); - } - - return UBL_OK; - } - -#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION +#endif // G26_MESH_VALIDATION diff --git a/Marlin/I2CPositionEncoder.h b/Marlin/I2CPositionEncoder.h index a582a87b6d..8380241855 100644 --- a/Marlin/I2CPositionEncoder.h +++ b/Marlin/I2CPositionEncoder.h @@ -127,10 +127,7 @@ invert = false, ec = true; - float axisOffset = 0; - - int32_t axisOffsetTicks = 0, - zeroOffset = 0, + int32_t zeroOffset = 0, lastPosition = 0, position; @@ -168,7 +165,7 @@ } FORCE_INLINE float get_position_mm() { return mm_from_count(get_position()); } - FORCE_INLINE int32_t get_position() { return get_raw_count() - zeroOffset - axisOffsetTicks; } + FORCE_INLINE int32_t get_position() { return get_raw_count() - zeroOffset; } int32_t get_axis_error_steps(const bool report); float get_axis_error_mm(const bool report); @@ -219,16 +216,6 @@ FORCE_INLINE int get_stepper_ticks() { return stepperTicks; } FORCE_INLINE void set_stepper_ticks(const int ticks) { stepperTicks = ticks; } - - FORCE_INLINE float get_axis_offset() { return axisOffset; } - FORCE_INLINE void set_axis_offset(const float newOffset) { - axisOffset = newOffset; - axisOffsetTicks = int32_t(axisOffset * get_encoder_ticks_mm()); - } - - FORCE_INLINE void set_current_position(const float newPositionMm) { - set_axis_offset(get_position_mm() - newPositionMm + axisOffset); - } }; class I2CPositionEncodersMgr { diff --git a/Marlin/Makefile b/Marlin/Makefile index 150f07439a..a2cea06269 100644 --- a/Marlin/Makefile +++ b/Marlin/Makefile @@ -304,13 +304,8 @@ ifeq ($(HARDWARE_VARIANT), Teensy) SRC = wiring.c VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy endif -CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \ - MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \ - SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \ - temperature.cpp cardreader.cpp configuration_store.cpp \ - watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ - dac_mcp4728.cpp vector_3.cpp least_squares_fit.cpp endstops.cpp stopwatch.cpp utility.cpp \ - printcounter.cpp nozzle.cpp serial.cpp gcode.cpp Max7219_Debug_LEDs.cpp +CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp Tone.cpp +CXXSRC += $(wildcard *.cpp) ifeq ($(NEOPIXEL), 1) CXXSRC += Adafruit_NeoPixel.cpp endif @@ -332,7 +327,7 @@ endif ifeq ($(RELOC_WORKAROUND), 1) LD_PREFIX=-nodefaultlibs -LD_SUFFIX=-lm -lgcc -lc -lgcc +LD_SUFFIX=-lm -lgcc -lc -lgcc -L$(ARDUINO_INSTALL_DIR)/hardware/tools/avr/avr/lib/avr6 -l$(MCU) endif #Check for Arduino 1.0.0 or higher and use the correct source files for that version diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index c341d98f31..fac820a814 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -210,17 +210,12 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); } /** * Feedrate scaling and conversion */ +extern float feedrate_mm_s; extern int16_t feedrate_percentage; -#define MMM_TO_MMS(MM_M) ((MM_M)/60.0) -#define MMS_TO_MMM(MM_S) ((MM_S)*60.0) #define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01) extern bool axis_relative_modes[]; -extern bool volumetric_enabled; -extern int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder -extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder. -extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern bool axis_known_position[XYZ]; extern bool axis_homed[XYZ]; extern volatile bool wait_for_heatup; @@ -229,7 +224,7 @@ extern volatile bool wait_for_heatup; extern volatile bool wait_for_user; #endif -extern float current_position[NUM_AXIS]; +extern float current_position[XYZE], destination[XYZE]; // Workspace offsets #if HAS_WORKSPACE_OFFSET @@ -252,14 +247,14 @@ extern float current_position[NUM_AXIS]; #define WORKSPACE_OFFSET(AXIS) 0 #endif -#define LOGICAL_POSITION(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS)) -#define RAW_POSITION(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS)) +#define NATIVE_TO_LOGICAL(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS)) +#define LOGICAL_TO_NATIVE(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS)) #if HAS_POSITION_SHIFT || DISABLED(DELTA) - #define LOGICAL_X_POSITION(POS) LOGICAL_POSITION(POS, X_AXIS) - #define LOGICAL_Y_POSITION(POS) LOGICAL_POSITION(POS, Y_AXIS) - #define RAW_X_POSITION(POS) RAW_POSITION(POS, X_AXIS) - #define RAW_Y_POSITION(POS) RAW_POSITION(POS, Y_AXIS) + #define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS) + #define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS) + #define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS) + #define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS) #else #define LOGICAL_X_POSITION(POS) (POS) #define LOGICAL_Y_POSITION(POS) (POS) @@ -267,9 +262,8 @@ extern float current_position[NUM_AXIS]; #define RAW_Y_POSITION(POS) (POS) #endif -#define LOGICAL_Z_POSITION(POS) LOGICAL_POSITION(POS, Z_AXIS) -#define RAW_Z_POSITION(POS) RAW_POSITION(POS, Z_AXIS) -#define RAW_CURRENT_POSITION(A) RAW_##A##_POSITION(current_position[A##_AXIS]) +#define LOGICAL_Z_POSITION(POS) NATIVE_TO_LOGICAL(POS, Z_AXIS) +#define RAW_Z_POSITION(POS) LOGICAL_TO_NATIVE(POS, Z_AXIS) // Hotend Offsets #if HOTENDS > 1 @@ -291,29 +285,81 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; void update_software_endstops(const AxisEnum axis); #endif +#if ENABLED(CNC_COORDINATE_SYSTEMS) + #define MAX_COORDINATE_SYSTEMS 9 + extern float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ]; + bool select_coordinate_system(const int8_t _new); +#endif + +void report_current_position(); + #if IS_KINEMATIC extern float delta[ABC]; - void inverse_kinematics(const float logical[XYZ]); + void inverse_kinematics(const float raw[XYZ]); #endif #if ENABLED(DELTA) - extern float endstop_adj[ABC], + extern float delta_height, + delta_endstop_adj[ABC], delta_radius, + delta_tower_angle_trim[ABC], + delta_tower[ABC][2], delta_diagonal_rod, delta_calibration_radius, + delta_diagonal_rod_2_tower[ABC], delta_segments_per_second, - delta_tower_angle_trim[ABC], delta_clip_start_height; - void recalc_delta_settings(float radius, float diagonal_rod, float tower_angle_trim[ABC]); + + void recalc_delta_settings(); + float delta_safe_distance_from_top(); + + #if ENABLED(DELTA_FAST_SQRT) + float Q_rsqrt(const float number); + #define _SQRT(n) (1.0f / Q_rsqrt(n)) + #else + #define _SQRT(n) SQRT(n) + #endif + + // Macro to obtain the Z position of an individual tower + #define DELTA_Z(T) raw[Z_AXIS] + _SQRT( \ + delta_diagonal_rod_2_tower[T] - HYPOT2( \ + delta_tower[T][X_AXIS] - raw[X_AXIS], \ + delta_tower[T][Y_AXIS] - raw[Y_AXIS] \ + ) \ + ) + + #define DELTA_RAW_IK() do { \ + delta[A_AXIS] = DELTA_Z(A_AXIS); \ + delta[B_AXIS] = DELTA_Z(B_AXIS); \ + delta[C_AXIS] = DELTA_Z(C_AXIS); \ + }while(0) + #elif IS_SCARA void forward_kinematics_SCARA(const float &a, const float &b); #endif +#if ENABLED(G26_MESH_VALIDATION) + extern bool g26_debug_flag; +#elif ENABLED(AUTO_BED_LEVELING_UBL) + constexpr bool g26_debug_flag = false; +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + #define _GET_MESH_X(I) (bilinear_start[X_AXIS] + (I) * bilinear_grid_spacing[X_AXIS]) + #define _GET_MESH_Y(J) (bilinear_start[Y_AXIS] + (J) * bilinear_grid_spacing[Y_AXIS]) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I) + #define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J) +#elif ENABLED(MESH_BED_LEVELING) + #define _GET_MESH_X(I) mbl.index_to_xpos[I] + #define _GET_MESH_Y(J) mbl.index_to_ypos[J] +#endif + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) extern int bilinear_grid_spacing[2], bilinear_start[2]; extern float bilinear_grid_factor[2], z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - float bilinear_z_offset(const float logical[XYZ]); + float bilinear_z_offset(const float raw[XYZ]); #endif #if ENABLED(AUTO_BED_LEVELING_UBL) @@ -323,22 +369,26 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; #if HAS_LEVELING bool leveling_is_valid(); - bool leveling_is_active(); void set_bed_leveling_enabled(const bool enable=true); void reset_bed_level(); #endif #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void set_z_fade_height(const float zfh); + void set_z_fade_height(const float zfh, const bool do_report=true); #endif +#if ENABLED(X_DUAL_ENDSTOPS) + extern float x_endstop_adj; +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + extern float y_endstop_adj; +#endif #if ENABLED(Z_DUAL_ENDSTOPS) extern float z_endstop_adj; #endif #if HAS_BED_PROBE extern float zprobe_zoffset; - void refresh_zprobe_zoffset(const bool no_babystep=false); #define DEPLOY_PROBE() set_probe_deployed(true) #define STOW_PROBE() set_probe_deployed(false) #else @@ -355,6 +405,10 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; #if FAN_COUNT > 0 extern int16_t fanSpeeds[FAN_COUNT]; + #if ENABLED(EXTRA_FAN_SPEED) + extern int16_t old_fanSpeeds[FAN_COUNT], + new_fanSpeeds[FAN_COUNT]; + #endif #if ENABLED(PROBING_FANS_OFF) extern bool fans_paused; extern int16_t paused_fanSpeeds[FAN_COUNT]; @@ -369,9 +423,9 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; extern bool filament_sensor; // Flag that filament sensor readings should control extrusion extern float filament_width_nominal, // Theoretical filament diameter i.e., 3.00 or 1.75 filament_width_meas; // Measured filament diameter - extern uint8_t meas_delay_cm, // Delay distance - measurement_delay[]; // Ring buffer to delay measurement - extern int8_t filwidth_delay_index[2]; // Ring buffer indexes. Used by planner, temperature, and main code + extern uint8_t meas_delay_cm; // Delay distance + extern int8_t measurement_delay[MAX_MEASUREMENT_DELAY + 1], // Ring buffer to delay measurement + filwidth_delay_index[2]; // Ring buffer indexes. Used by planner, temperature, and main code #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) @@ -404,15 +458,13 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; // Handling multiple extruders pins extern uint8_t active_extruder; -#if HAS_TEMP_HOTEND || HAS_TEMP_BED - void print_heaterstates(); -#endif - #if ENABLED(MIXING_EXTRUDER) extern float mixing_factor[MIXING_STEPPERS]; #endif -void calculate_volumetric_multipliers(); +inline void set_current_from_destination() { COPY(current_position, destination); } +inline void set_destination_from_current() { COPY(destination, current_position); } +void prepare_move_to_destination(); /** * Blocking movement and shorthand functions @@ -430,6 +482,7 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s || ENABLED(NOZZLE_CLEAN_FEATURE) \ || ENABLED(NOZZLE_PARK_FEATURE) \ || (ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(HOME_BEFORE_FILAMENT_CHANGE)) \ + || HAS_M206_COMMAND \ ) || ENABLED(NO_MOTION_BEFORE_HOMING) #if HAS_AXIS_UNHOMED_ERR @@ -446,7 +499,7 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s extern const float L1, L2; #endif - inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { + inline bool position_is_reachable(const float &rx, const float &ry) { #if ENABLED(DELTA) return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS); #elif IS_SCARA @@ -461,24 +514,24 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s #endif } - inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { + inline bool position_is_reachable_by_probe(const float &rx, const float &ry) { // Both the nozzle and the probe must be able to reach the point. // This won't work on SCARA since the probe offset rotates with the arm. - return position_is_reachable_raw_xy(rx, ry) - && position_is_reachable_raw_xy(rx - X_PROBE_OFFSET_FROM_EXTRUDER, ry - Y_PROBE_OFFSET_FROM_EXTRUDER); + return position_is_reachable(rx, ry) + && position_is_reachable(rx - (X_PROBE_OFFSET_FROM_EXTRUDER), ry - (Y_PROBE_OFFSET_FROM_EXTRUDER)); } #else // CARTESIAN - inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { + inline bool position_is_reachable(const float &rx, const float &ry) { // Add 0.001 margin to deal with float imprecision return WITHIN(rx, X_MIN_POS - 0.001, X_MAX_POS + 0.001) && WITHIN(ry, Y_MIN_POS - 0.001, Y_MAX_POS + 0.001); } - inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { + inline bool position_is_reachable_by_probe(const float &rx, const float &ry) { // Add 0.001 margin to deal with float imprecision return WITHIN(rx, MIN_PROBE_X - 0.001, MAX_PROBE_X + 0.001) && WITHIN(ry, MIN_PROBE_Y - 0.001, MAX_PROBE_Y + 0.001); @@ -486,12 +539,4 @@ void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s #endif // CARTESIAN -FORCE_INLINE bool position_is_reachable_by_probe_xy(const float &lx, const float &ly) { - return position_is_reachable_by_probe_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly)); -} - -FORCE_INLINE bool position_is_reachable_xy(const float &lx, const float &ly) { - return position_is_reachable_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly)); -} - #endif // MARLIN_H diff --git a/Marlin/MarlinConfig.h b/Marlin/MarlinConfig.h index 64e0bac51f..fdab3d462b 100644 --- a/Marlin/MarlinConfig.h +++ b/Marlin/MarlinConfig.h @@ -29,6 +29,7 @@ #include "Version.h" #include "Configuration.h" #include "Conditionals_LCD.h" +#include "tmc_macros.h" #include "Configuration_adv.h" #include "pins.h" #ifndef USBCON diff --git a/Marlin/spi.h b/Marlin/MarlinSPI.h similarity index 95% rename from Marlin/spi.h rename to Marlin/MarlinSPI.h index c4b86005ad..93f9fb2b08 100644 --- a/Marlin/spi.h +++ b/Marlin/MarlinSPI.h @@ -20,8 +20,8 @@ * */ -#ifndef __SPI_H__ -#define __SPI_H__ +#ifndef __MARLIN_SPI_H__ +#define __MARLIN_SPI_H__ #include #include "softspi.h" @@ -54,4 +54,4 @@ class SPI { }; -#endif // __SPI_H__ +#endif // __MARLIN_SPI_H__ diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h index 6282c8943a..b3b5096591 100644 --- a/Marlin/MarlinSerial.h +++ b/Marlin/MarlinSerial.h @@ -75,28 +75,18 @@ #define BIN 2 #define BYTE 0 -#ifndef USBCON - // Define constants and variables for buffering incoming serial data. We're - // using a ring buffer (I think), in which rx_buffer_head is the index of the - // location to which to write the next incoming character and rx_buffer_tail - // is the index of the location from which to read. - // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256) - #ifndef RX_BUFFER_SIZE - #define RX_BUFFER_SIZE 128 - #endif - #ifndef TX_BUFFER_SIZE - #define TX_BUFFER_SIZE 32 - #endif +// Define constants and variables for buffering serial data. +// Use only 0 or powers of 2 greater than 1 +// : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...] +#ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 +#endif +// 256 is the max TX buffer limit due to uint8_t head and tail. +#ifndef TX_BUFFER_SIZE + #define TX_BUFFER_SIZE 32 +#endif - #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 - #error "XON/XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." - #endif - #if !IS_POWER_OF_2(RX_BUFFER_SIZE) || RX_BUFFER_SIZE < 2 - #error "RX_BUFFER_SIZE must be a power of 2 greater than 1." - #endif - #if TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE)) - #error "TX_BUFFER_SIZE must be 0 or a power of 2 greater than 1." - #endif +#ifndef USBCON #if RX_BUFFER_SIZE > 256 typedef uint16_t ring_buffer_pos_t; @@ -143,10 +133,10 @@ static void printFloat(double, uint8_t); public: - static FORCE_INLINE void write(const char* str) { while (*str) write(*str++); } - static FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); } - static FORCE_INLINE void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); } - static FORCE_INLINE void print(const char* str) { write(str); } + FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); } + FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); } + FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); } + FORCE_INLINE static void print(const char* str) { write(str); } static void print(char, int = BYTE); static void print(unsigned char, int = BYTE); diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 3ac04338f1..4e817536bf 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -59,7 +59,7 @@ * G19 - Select Plane YZ (Requires CNC_WORKSPACE_PLANES) * G20 - Set input units to inches (Requires INCH_MODE_SUPPORT) * G21 - Set input units to millimeters (Requires INCH_MODE_SUPPORT) - * G26 - Mesh Validation Pattern (Requires UBL_G26_MESH_VALIDATION) + * G26 - Mesh Validation Pattern (Requires G26_MESH_VALIDATION) * G27 - Park Nozzle (Requires NOZZLE_PARK_FEATURE) * G28 - Home one or more axes * G29 - Start or continue the bed leveling probe procedure (Requires bed leveling) @@ -68,7 +68,7 @@ * G32 - Undock sled (Z_PROBE_SLED only) * G33 - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION) * G38 - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET) - * G42 - Coordinated move to a mesh point (Requires AUTO_BED_LEVELING_UBL) + * G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL) * G90 - Use Absolute Coordinates * G91 - Use Relative Coordinates * G92 - Set current position to coordinates given @@ -117,8 +117,8 @@ * M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER) * M104 - Set extruder target temp. * M105 - Report current temperatures. - * M106 - Fan on. - * M107 - Fan off. + * M106 - Set print fan speed. + * M107 - Print fan off. * M108 - Break out of heating loops (M109, M190, M303). With no controller, breaks out of M0/M1. (Requires EMERGENCY_PARSER) * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling @@ -134,6 +134,7 @@ * M119 - Report endstops status. * M120 - Enable endstops detection. * M121 - Disable endstops detection. + * M122 - Debug stepper (Requires HAVE_TMC2130) * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE) * M126 - Solenoid Air Valve Open. (Requires BARICUDA) * M127 - Solenoid Air Valve Closed. (Requires BARICUDA) @@ -173,6 +174,7 @@ * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS) * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS) * M280 - Set servo position absolute: "M280 P S". (Requires servos) + * M290 - Babystepping (Requires BABYSTEPPING) * M300 - Play beep sound S P * M301 - Set PID parameters P I and D. (Requires PIDTEMP) * M302 - Allow cold extrudes, or set the minimum extrude S. (Requires PREVENT_COLD_EXTRUSION) @@ -204,6 +206,7 @@ * M666 - Set delta endstop adjustment. (Requires DELTA) * M605 - Set dual x-carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.) + * M852 - Set skew factors: "M852 [I] [J] [K]". (Requires SKEW_CORRECTION_GCODE, and SKEW_CORRECTION_FOR_Z for IJ) * M860 - Report the position of position encoder modules. * M861 - Report the status of position encoder modules. * M862 - Perform an axis continuity test for position encoder modules. @@ -215,13 +218,13 @@ * M868 - Report or set position encoder module error correction threshold. * M869 - Report position encoder module error. * M900 - Get and/or Set advance K factor and WH/D ratio. (Requires LIN_ADVANCE) - * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires HAVE_TMC2130) + * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires HAVE_TMC2130 or HAVE_TMC2208) * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots) * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN) * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT) * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT) - * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130) - * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130) + * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130 or HAVE_TMC2208) + * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130 or HAVE_TMC2208) * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) * M914 - Set SENSORLESS_HOMING sensitivity. (Requires SENSORLESS_HOMING) * @@ -283,17 +286,8 @@ #include "Max7219_Debug_LEDs.h" #endif -#if ENABLED(NEOPIXEL_LED) - #include -#endif - -#if ENABLED(BLINKM) - #include "blinkm.h" - #include "Wire.h" -#endif - -#if ENABLED(PCA9632) - #include "pca9632.h" +#if HAS_COLOR_LEDS + #include "leds.h" #endif #if HAS_SERVOS @@ -325,6 +319,11 @@ void M100_dump_routine(const char * const title, const char *start, const char *end); #endif +#if ENABLED(G26_MESH_VALIDATION) + bool g26_debug_flag; // =false + void gcode_G26(); +#endif + #if ENABLED(SDSUPPORT) CardReader card; #endif @@ -342,25 +341,11 @@ #include "ubl.h" extern bool defer_return_to_status; unified_bed_leveling ubl; - #define UBL_MESH_VALID !( ( ubl.z_values[0][0] == ubl.z_values[0][1] && ubl.z_values[0][1] == ubl.z_values[0][2] \ - && ubl.z_values[1][0] == ubl.z_values[1][1] && ubl.z_values[1][1] == ubl.z_values[1][2] \ - && ubl.z_values[2][0] == ubl.z_values[2][1] && ubl.z_values[2][1] == ubl.z_values[2][2] \ - && ubl.z_values[0][0] == 0 && ubl.z_values[1][0] == 0 && ubl.z_values[2][0] == 0 ) \ - || isnan(ubl.z_values[0][0])) #endif -#if ENABLED(NEOPIXEL_LED) - #if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR - #define NEO_WHITE 255, 255, 255 - #else - #define NEO_WHITE 0, 0, 0, 255 - #endif -#endif - -#if ENABLED(RGB_LED) || ENABLED(BLINKM) || ENABLED(PCA9632) - #define LED_WHITE 255, 255, 255 -#elif ENABLED(RGBW_LED) - #define LED_WHITE 0, 0, 0, 255 +#if ENABLED(CNC_COORDINATE_SYSTEMS) + int8_t active_coordinate_system = -1; // machine space + float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ]; #endif bool Running = true; @@ -369,17 +354,17 @@ uint8_t marlin_debug_flags = DEBUG_NONE; /** * Cartesian Current Position - * Used to track the logical position as moves are queued. - * Used by 'line_to_current_position' to do a move after changing it. + * Used to track the native machine position as moves are queued. + * Used by 'buffer_line_to_current_position' to do a move after changing it. * Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'. */ float current_position[XYZE] = { 0.0 }; /** * Cartesian Destination - * A temporary position, usually applied to 'current_position'. - * Set with 'gcode_get_destination' or 'set_destination_to_current'. - * 'line_to_destination' sets 'current_position' to 'destination'. + * The destination for a move, filled in by G-code movement commands, + * and expected by functions like 'prepare_move_to_destination'. + * Set with 'gcode_get_destination' or 'set_destination_from_current'. */ float destination[XYZE] = { 0.0 }; @@ -446,13 +431,10 @@ FORCE_INLINE float homing_feedrate(const AxisEnum a) { return pgm_read_float(&ho float feedrate_mm_s = MMM_TO_MMS(1500.0); static float saved_feedrate_mm_s; -int16_t feedrate_percentage = 100, saved_feedrate_percentage, - flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); +int16_t feedrate_percentage = 100, saved_feedrate_percentage; // Initialized by settings.load() -bool axis_relative_modes[] = AXIS_RELATIVE_MODES, - volumetric_enabled; -float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS]; +bool axis_relative_modes[] = AXIS_RELATIVE_MODES; #if HAS_WORKSPACE_OFFSET #if HAS_POSITION_SHIFT @@ -471,14 +453,21 @@ float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS]; #endif // Software Endstops are based on the configured limits. -#if HAS_SOFTWARE_ENDSTOPS - bool soft_endstops_enabled = true; -#endif float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, soft_endstop_max[XYZ] = { X_MAX_BED, Y_MAX_BED, Z_MAX_POS }; +#if HAS_SOFTWARE_ENDSTOPS + bool soft_endstops_enabled = true; + #if IS_KINEMATIC + float soft_endstop_radius, soft_endstop_radius_2; + #endif +#endif #if FAN_COUNT > 0 int16_t fanSpeeds[FAN_COUNT] = { 0 }; + #if ENABLED(EXTRA_FAN_SPEED) + int16_t old_fanSpeeds[FAN_COUNT], + new_fanSpeeds[FAN_COUNT]; + #endif #if ENABLED(PROBING_FANS_OFF) bool fans_paused = false; int16_t paused_fanSpeeds[FAN_COUNT] = { 0 }; @@ -526,7 +515,7 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL #define BUZZ(d,f) NOOP #endif -static uint8_t target_extruder; +uint8_t target_extruder; #if HAS_BED_PROBE float zprobe_zoffset; // Initialized by settings.load() @@ -544,26 +533,32 @@ static uint8_t target_extruder; #if ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(DELTA) #define ADJUST_DELTA(V) \ - if (planner.abl_enabled) { \ + if (planner.leveling_active) { \ const float zadj = bilinear_z_offset(V); \ delta[A_AXIS] += zadj; \ delta[B_AXIS] += zadj; \ delta[C_AXIS] += zadj; \ } #else - #define ADJUST_DELTA(V) if (planner.abl_enabled) { delta[Z_AXIS] += bilinear_z_offset(V); } + #define ADJUST_DELTA(V) if (planner.leveling_active) { delta[Z_AXIS] += bilinear_z_offset(V); } #endif #elif IS_KINEMATIC #define ADJUST_DELTA(V) NOOP #endif +#if ENABLED(X_DUAL_ENDSTOPS) + float x_endstop_adj; // Initialized by settings.load() +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + float y_endstop_adj; // Initialized by settings.load() +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - float z_endstop_adj; + float z_endstop_adj; // Initialized by settings.load() #endif // Extruder offsets #if HOTENDS > 1 - float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load() + float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load() #endif #if HAS_Z_SERVO_ENDSTOP @@ -605,11 +600,12 @@ static uint8_t target_extruder; #if ENABLED(DELTA) - float delta[ABC], - endstop_adj[ABC] = { 0 }; + float delta[ABC]; // Initialized by settings.load() - float delta_radius, + float delta_height, + delta_endstop_adj[ABC] = { 0 }, + delta_radius, delta_tower_angle_trim[ABC], delta_tower[ABC][2], delta_diagonal_rod, @@ -644,9 +640,9 @@ float cartes[XYZ] = { 0 }; bool filament_sensor = false; // M405 turns on filament sensor control. M406 turns it off. float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA, // Nominal filament width. Change with M404. filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; // Measured filament diameter - uint8_t meas_delay_cm = MEASUREMENT_DELAY_CM, // Distance delay setting - measurement_delay[MAX_MEASUREMENT_DELAY + 1]; // Ring buffer to delayed measurement. Store extruder factor after subtracting 100 - int8_t filwidth_delay_index[2] = { 0, -1 }; // Indexes into ring buffer + uint8_t meas_delay_cm = MEASUREMENT_DELAY_CM; // Distance delay setting + int8_t measurement_delay[MAX_MEASUREMENT_DELAY + 1], // Ring buffer to delayed measurement. Store extruder factor after subtracting 100 + filwidth_delay_index[2] = { 0, -1 }; // Indexes into ring buffer #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) @@ -680,10 +676,6 @@ static bool send_ok[BUFSIZE]; bool chdkActive = false; #endif -#ifdef AUTOMATIC_CURRENT_CONTROL - bool auto_current_control = 0; -#endif - #if ENABLED(PID_EXTRUSION_SCALING) int lpq_len = 20; #endif @@ -711,7 +703,7 @@ FORCE_INLINE signed char pgm_read_any(const signed char *p) { return pgm_read_by #define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \ static const PROGMEM type array##_P[XYZ] = { X_##CONFIG, Y_##CONFIG, Z_##CONFIG }; \ - static inline type array(AxisEnum axis) { return pgm_read_any(&array##_P[axis]); } \ + static inline type array(const AxisEnum axis) { return pgm_read_any(&array##_P[axis]); } \ typedef void __void_##CONFIG##__ XYZ_CONSTS_FROM_CONFIG(float, base_min_pos, MIN_POS); @@ -731,17 +723,17 @@ void stop(); void get_available_commands(); void process_next_command(); -void prepare_move_to_destination(); +void process_parsed_command(); void get_cartesian_from_steppers(); void set_current_from_steppers_for_axis(const AxisEnum axis); #if ENABLED(ARC_SUPPORT) - void plan_arc(float target[XYZE], float* offset, uint8_t clockwise); + void plan_arc(const float (&cart)[XYZE], const float (&offset)[2], const bool clockwise); #endif #if ENABLED(BEZIER_CURVE_SUPPORT) - void plan_cubic_move(const float offset[4]); + void plan_cubic_move(const float (&offset)[4]); #endif void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false); @@ -990,98 +982,6 @@ void servo_init() { #endif -#if HAS_COLOR_LEDS - - #if ENABLED(NEOPIXEL_LED) - - Adafruit_NeoPixel pixels(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800); - - void set_neopixel_color(const uint32_t color) { - for (uint16_t i = 0; i < pixels.numPixels(); ++i) - pixels.setPixelColor(i, color); - pixels.show(); - } - - void setup_neopixel() { - pixels.setBrightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range - pixels.begin(); - pixels.show(); // initialize to all off - - #if ENABLED(NEOPIXEL_STARTUP_TEST) - delay(2000); - set_neopixel_color(pixels.Color(255, 0, 0, 0)); // red - delay(2000); - set_neopixel_color(pixels.Color(0, 255, 0, 0)); // green - delay(2000); - set_neopixel_color(pixels.Color(0, 0, 255, 0)); // blue - delay(2000); - #endif - set_neopixel_color(pixels.Color(NEO_WHITE)); // white - } - - #endif // NEOPIXEL_LED - - void set_led_color( - const uint8_t r, const uint8_t g, const uint8_t b - #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED) - , const uint8_t w = 0 - #if ENABLED(NEOPIXEL_LED) - , const uint8_t p = NEOPIXEL_BRIGHTNESS - , bool isSequence = false - #endif - #endif - ) { - - #if ENABLED(NEOPIXEL_LED) - - const uint32_t color = pixels.Color(r, g, b, w); - static uint16_t nextLed = 0; - - pixels.setBrightness(p); - if (!isSequence) - set_neopixel_color(color); - else { - pixels.setPixelColor(nextLed, color); - pixels.show(); - if (++nextLed >= pixels.numPixels()) nextLed = 0; - return; - } - - #endif - - #if ENABLED(BLINKM) - - // This variant uses i2c to send the RGB components to the device. - SendColors(r, g, b); - - #endif - - #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) - - // This variant uses 3 separate pins for the RGB components. - // If the pins can do PWM then their intensity will be set. - WRITE(RGB_LED_R_PIN, r ? HIGH : LOW); - WRITE(RGB_LED_G_PIN, g ? HIGH : LOW); - WRITE(RGB_LED_B_PIN, b ? HIGH : LOW); - analogWrite(RGB_LED_R_PIN, r); - analogWrite(RGB_LED_G_PIN, g); - analogWrite(RGB_LED_B_PIN, b); - - #if ENABLED(RGBW_LED) - WRITE(RGB_LED_W_PIN, w ? HIGH : LOW); - analogWrite(RGB_LED_W_PIN, w); - #endif - - #endif - - #if ENABLED(PCA9632) - // Update I2C LED driver - PCA9632_SetColor(r, g, b); - #endif - } - -#endif // HAS_COLOR_LEDS - void gcode_line_error(const char* err, bool doFlush = true) { SERIAL_ERROR_START(); serialprintPGM(err); @@ -1124,18 +1024,17 @@ inline void get_serial_commands() { */ if (serial_char == '\n' || serial_char == '\r') { - serial_comment_mode = false; // end of line == end of comment + serial_comment_mode = false; // end of line == end of comment - if (!serial_count) continue; // skip empty lines + if (!serial_count) continue; // Skip empty lines - serial_line_buffer[serial_count] = 0; // terminate string - serial_count = 0; //reset buffer + serial_line_buffer[serial_count] = 0; // Terminate string + serial_count = 0; // Reset buffer char* command = serial_line_buffer; - while (*command == ' ') command++; // skip any leading spaces - char *npos = (*command == 'N') ? command : NULL, // Require the N parameter to start the line - *apos = strchr(command, '*'); + while (*command == ' ') command++; // Skip leading spaces + char *npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line if (npos) { @@ -1153,15 +1052,14 @@ inline void get_serial_commands() { return; } + char *apos = strrchr(command, '*'); if (apos) { - byte checksum = 0, count = 0; - while (command[count] != '*') checksum ^= command[count++]; - + uint8_t checksum = 0, count = uint8_t(apos - command); + while (count) checksum ^= command[--count]; if (strtol(apos + 1, NULL, 10) != checksum) { gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH)); return; } - // if no errors, continue parsing } else { gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM)); @@ -1169,11 +1067,6 @@ inline void get_serial_commands() { } gcode_LastN = gcode_N; - // if no errors, continue parsing - } - else if (apos) { // No '*' without 'N' - gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false); - return; } // Movement commands alert when stopped @@ -1265,19 +1158,25 @@ inline void get_serial_commands() { || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode) ) { if (card_eof) { - SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + card.printingHasFinished(); - #if ENABLED(PRINTER_EVENT_LEDS) - LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS); - set_led_color(0, 255, 0); // Green - #if HAS_RESUME_CONTINUE - enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue! - #else - safe_delay(1000); + + if (card.sdprinting) + sd_count = 0; // If a sub-file was printing, continue from call point + else { + SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + #if ENABLED(PRINTER_EVENT_LEDS) + LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS); + leds.set_green(); + #if HAS_RESUME_CONTINUE + enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue! + #else + safe_delay(1000); + #endif + leds.set_off(); #endif - set_led_color(0, 0, 0); // OFF - #endif - card.checkautostart(true); + card.checkautostart(true); + } } else if (n == -1) { SERIAL_ERROR_START(); @@ -1360,7 +1259,7 @@ bool get_target_extruder_from_command(const uint16_t code) { static float x_home_pos(const int extruder) { if (extruder == 0) - return LOGICAL_X_POSITION(base_home_pos(X_AXIS)); + return base_home_pos(X_AXIS); else /** * In dual carriage mode the extruder offset provides an override of the @@ -1368,7 +1267,7 @@ bool get_target_extruder_from_command(const uint16_t code) { * This allows soft recalibration of the second extruder home position * without firmware reflash (through the M218 command). */ - return LOGICAL_X_POSITION(hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS); + return hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS; } static int x_home_dir(const int extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } @@ -1394,17 +1293,8 @@ bool get_target_extruder_from_command(const uint16_t code) { * at the same positions relative to the machine. */ void update_software_endstops(const AxisEnum axis) { - const float offs = 0.0 - #if HAS_HOME_OFFSET - + home_offset[axis] - #endif - #if HAS_POSITION_SHIFT - + position_shift[axis] - #endif - ; - #if HAS_HOME_OFFSET && HAS_POSITION_SHIFT - workspace_offset[axis] = offs; + workspace_offset[axis] = home_offset[axis] + position_shift[axis]; #endif #if ENABLED(DUAL_X_CARRIAGE) @@ -1415,27 +1305,27 @@ bool get_target_extruder_from_command(const uint16_t code) { if (active_extruder != 0) { // T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger) - soft_endstop_min[X_AXIS] = X2_MIN_POS + offs; - soft_endstop_max[X_AXIS] = dual_max_x + offs; + soft_endstop_min[X_AXIS] = X2_MIN_POS; + soft_endstop_max[X_AXIS] = dual_max_x; } else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { // In Duplication Mode, T0 can move as far left as X_MIN_POS // but not so far to the right that T1 would move past the end - soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs; - soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; + soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS); + soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset); } else { // In other modes, T0 can move from X_MIN_POS to X_MAX_POS - soft_endstop_min[axis] = base_min_pos(axis) + offs; - soft_endstop_max[axis] = base_max_pos(axis) + offs; + soft_endstop_min[axis] = base_min_pos(axis); + soft_endstop_max[axis] = base_max_pos(axis); } } #elif ENABLED(DELTA) - soft_endstop_min[axis] = base_min_pos(axis) + (axis == Z_AXIS ? 0 : offs); - soft_endstop_max[axis] = base_max_pos(axis) + offs; + soft_endstop_min[axis] = base_min_pos(axis); + soft_endstop_max[axis] = axis == Z_AXIS ? delta_height : base_max_pos(axis); #else - soft_endstop_min[axis] = base_min_pos(axis) + offs; - soft_endstop_max[axis] = base_max_pos(axis) + offs; + soft_endstop_min[axis] = base_min_pos(axis); + soft_endstop_max[axis] = base_max_pos(axis); #endif #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -1453,8 +1343,17 @@ bool get_target_extruder_from_command(const uint16_t code) { #endif #if ENABLED(DELTA) - if (axis == Z_AXIS) - delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top(); + switch(axis) { + case X_AXIS: + case Y_AXIS: + // Get a minimum radius for clamping + soft_endstop_radius = MIN3(FABS(max(soft_endstop_min[X_AXIS], soft_endstop_min[Y_AXIS])), soft_endstop_max[X_AXIS], soft_endstop_max[Y_AXIS]); + soft_endstop_radius_2 = sq(soft_endstop_radius); + break; + case Z_AXIS: + delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top(); + default: break; + } #endif } @@ -1470,7 +1369,6 @@ bool get_target_extruder_from_command(const uint16_t code) { * call sync_plan_position soon after this. */ static void set_home_offset(const AxisEnum axis, const float v) { - current_position[axis] += v - home_offset[axis]; home_offset[axis] = v; update_software_endstops(axis); } @@ -1524,8 +1422,11 @@ static void set_axis_is_at_home(const AxisEnum axis) { */ if (axis == X_AXIS || axis == Y_AXIS) { - float homeposition[XYZ]; - LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos((AxisEnum)i), i); + float homeposition[XYZ] = { + base_home_pos(X_AXIS), + base_home_pos(Y_AXIS), + base_home_pos(Z_AXIS) + }; // SERIAL_ECHOPAIR("homeposition X:", homeposition[X_AXIS]); // SERIAL_ECHOLNPAIR(" Y:", homeposition[Y_AXIS]); @@ -1540,7 +1441,7 @@ static void set_axis_is_at_home(const AxisEnum axis) { // SERIAL_ECHOPAIR("Cartesian X:", cartes[X_AXIS]); // SERIAL_ECHOLNPAIR(" Y:", cartes[Y_AXIS]); - current_position[axis] = LOGICAL_POSITION(cartes[axis], axis); + current_position[axis] = cartes[axis]; /** * SCARA home positions are based on configuration since the actual @@ -1550,9 +1451,13 @@ static void set_axis_is_at_home(const AxisEnum axis) { soft_endstop_max[axis] = base_max_pos(axis); // + (cartes[axis] - base_home_pos(axis)); } else + #elif ENABLED(DELTA) + if (axis == Z_AXIS) + current_position[axis] = delta_height; + else #endif { - current_position[axis] = LOGICAL_POSITION(base_home_pos(axis), axis); + current_position[axis] = base_home_pos(axis); } /** @@ -1615,7 +1520,7 @@ inline float get_homing_bump_feedrate(const AxisEnum axis) { * Move the planner to the current position from wherever it last moved * (or from wherever it has been told it is located). */ -inline void line_to_current_position() { +inline void buffer_line_to_current_position() { planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate_mm_s, active_extruder); } @@ -1623,13 +1528,9 @@ inline void line_to_current_position() { * Move the planner to the position stored in the destination array, which is * used by G0/G1/G2/G3/G5 and many other functions to set a destination. */ -inline void line_to_destination(const float fr_mm_s) { +inline void buffer_line_to_destination(const float fr_mm_s) { planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], fr_mm_s, active_extruder); } -inline void line_to_destination() { line_to_destination(feedrate_mm_s); } - -inline void set_current_to_destination() { COPY(current_position, destination); } -inline void set_destination_to_current() { COPY(destination, current_position); } #if IS_KINEMATIC /** @@ -1642,7 +1543,7 @@ inline void set_destination_to_current() { COPY(destination, current_position); refresh_cmd_timeout(); - #if UBL_DELTA + #if UBL_SEGMENTED // ubl segmented line will do z-only moves in single segment ubl.prepare_segmented_line_to(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s)); #else @@ -1655,7 +1556,7 @@ inline void set_destination_to_current() { COPY(destination, current_position); planner.buffer_line_kinematic(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder); #endif - set_current_to_destination(); + set_current_from_destination(); } #endif // IS_KINEMATIC @@ -1663,64 +1564,64 @@ inline void set_destination_to_current() { COPY(destination, current_position); * Plan a move to (X, Y, Z) and set the current_position * The final current_position may not be the one that was requested */ -void do_blocking_move_to(const float &lx, const float &ly, const float &lz, const float &fr_mm_s/*=0.0*/) { +void do_blocking_move_to(const float &rx, const float &ry, const float &rz, const float &fr_mm_s/*=0.0*/) { const float old_feedrate_mm_s = feedrate_mm_s; #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, lx, ly, lz); + if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, LOGICAL_X_POSITION(rx), LOGICAL_Y_POSITION(ry), LOGICAL_Z_POSITION(rz)); #endif + const float z_feedrate = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); + #if ENABLED(DELTA) - if (!position_is_reachable_xy(lx, ly)) return; + if (!position_is_reachable(rx, ry)) return; feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; - set_destination_to_current(); // sync destination at the start + set_destination_from_current(); // sync destination at the start #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) DEBUG_POS("set_destination_to_current", destination); + if (DEBUGGING(LEVELING)) DEBUG_POS("set_destination_from_current", destination); #endif // when in the danger zone if (current_position[Z_AXIS] > delta_clip_start_height) { - if (lz > delta_clip_start_height) { // staying in the danger zone - destination[X_AXIS] = lx; // move directly (uninterpolated) - destination[Y_AXIS] = ly; - destination[Z_AXIS] = lz; - prepare_uninterpolated_move_to_destination(); // set_current_to_destination + if (rz > delta_clip_start_height) { // staying in the danger zone + destination[X_AXIS] = rx; // move directly (uninterpolated) + destination[Y_AXIS] = ry; + destination[Z_AXIS] = rz; + prepare_uninterpolated_move_to_destination(); // set_current_from_destination #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); #endif return; } - else { - destination[Z_AXIS] = delta_clip_start_height; - prepare_uninterpolated_move_to_destination(); // set_current_to_destination - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position); - #endif - } + destination[Z_AXIS] = delta_clip_start_height; + prepare_uninterpolated_move_to_destination(); // set_current_from_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position); + #endif } - if (lz > current_position[Z_AXIS]) { // raising? - destination[Z_AXIS] = lz; - prepare_uninterpolated_move_to_destination(); // set_current_to_destination + if (rz > current_position[Z_AXIS]) { // raising? + destination[Z_AXIS] = rz; + prepare_uninterpolated_move_to_destination(z_feedrate); // set_current_from_destination #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position); #endif } - destination[X_AXIS] = lx; - destination[Y_AXIS] = ly; - prepare_move_to_destination(); // set_current_to_destination + destination[X_AXIS] = rx; + destination[Y_AXIS] = ry; + prepare_move_to_destination(); // set_current_from_destination #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position); #endif - if (lz < current_position[Z_AXIS]) { // lowering? - destination[Z_AXIS] = lz; - prepare_uninterpolated_move_to_destination(); // set_current_to_destination + if (rz < current_position[Z_AXIS]) { // lowering? + destination[Z_AXIS] = rz; + prepare_uninterpolated_move_to_destination(z_feedrate); // set_current_from_destination #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position); #endif @@ -1728,45 +1629,45 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons #elif IS_SCARA - if (!position_is_reachable_xy(lx, ly)) return; + if (!position_is_reachable(rx, ry)) return; - set_destination_to_current(); + set_destination_from_current(); // If Z needs to raise, do it before moving XY - if (destination[Z_AXIS] < lz) { - destination[Z_AXIS] = lz; - prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); + if (destination[Z_AXIS] < rz) { + destination[Z_AXIS] = rz; + prepare_uninterpolated_move_to_destination(z_feedrate); } - destination[X_AXIS] = lx; - destination[Y_AXIS] = ly; + destination[X_AXIS] = rx; + destination[Y_AXIS] = ry; prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S); // If Z needs to lower, do it after moving XY - if (destination[Z_AXIS] > lz) { - destination[Z_AXIS] = lz; - prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); + if (destination[Z_AXIS] > rz) { + destination[Z_AXIS] = rz; + prepare_uninterpolated_move_to_destination(z_feedrate); } #else // If Z needs to raise, do it before moving XY - if (current_position[Z_AXIS] < lz) { - feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); - current_position[Z_AXIS] = lz; - line_to_current_position(); + if (current_position[Z_AXIS] < rz) { + feedrate_mm_s = z_feedrate; + current_position[Z_AXIS] = rz; + buffer_line_to_current_position(); } feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; - current_position[X_AXIS] = lx; - current_position[Y_AXIS] = ly; - line_to_current_position(); + current_position[X_AXIS] = rx; + current_position[Y_AXIS] = ry; + buffer_line_to_current_position(); // If Z needs to lower, do it after moving XY - if (current_position[Z_AXIS] > lz) { - feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); - current_position[Z_AXIS] = lz; - line_to_current_position(); + if (current_position[Z_AXIS] > rz) { + feedrate_mm_s = z_feedrate; + current_position[Z_AXIS] = rz; + buffer_line_to_current_position(); } #endif @@ -1779,14 +1680,14 @@ void do_blocking_move_to(const float &lx, const float &ly, const float &lz, cons if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to"); #endif } -void do_blocking_move_to_x(const float &lx, const float &fr_mm_s/*=0.0*/) { - do_blocking_move_to(lx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s); +void do_blocking_move_to_x(const float &rx, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(rx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s); } -void do_blocking_move_to_z(const float &lz, const float &fr_mm_s/*=0.0*/) { - do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], lz, fr_mm_s); +void do_blocking_move_to_z(const float &rz, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], rz, fr_mm_s); } -void do_blocking_move_to_xy(const float &lx, const float &ly, const float &fr_mm_s/*=0.0*/) { - do_blocking_move_to(lx, ly, current_position[Z_AXIS], fr_mm_s); +void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(rx, ry, current_position[Z_AXIS], fr_mm_s); } // @@ -1900,8 +1801,8 @@ static void clean_up_after_endstop_or_probe_move() { #elif ENABLED(Z_PROBE_ALLEN_KEY) - FORCE_INLINE void do_blocking_move_to(const float logical[XYZ], const float &fr_mm_s) { - do_blocking_move_to(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS], fr_mm_s); + FORCE_INLINE void do_blocking_move_to(const float (&raw)[XYZ], const float &fr_mm_s) { + do_blocking_move_to(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], fr_mm_s); } void run_deploy_moves_script() { @@ -2302,13 +2203,12 @@ static void clean_up_after_endstop_or_probe_move() { } /** - * @details Used by probe_pt to do a single Z probe. + * @details Used by probe_pt to do a single Z probe at the current position. * Leaves current_position[Z_AXIS] at the height where the probe triggered. * - * @param short_move Flag for a shorter probe move towards the bed * @return The raw Z position where the probe was triggered */ - static float run_z_probe(const bool short_move=true) { + static float run_z_probe() { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS(">>> run_z_probe", current_position); @@ -2317,13 +2217,15 @@ static void clean_up_after_endstop_or_probe_move() { // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding refresh_cmd_timeout(); - #if ENABLED(PROBE_DOUBLE_TOUCH) + // Double-probing does a fast probe followed by a slow probe + #if MULTIPLE_PROBING == 2 // Do a first probe at the fast speed if (do_probe_move(-10, Z_PROBE_SPEED_FAST)) return NAN; + float first_probe_z = current_position[Z_AXIS]; + #if ENABLED(DEBUG_LEVELING_FEATURE) - float first_probe_z = current_position[Z_AXIS]; if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("1st Probe Z:", first_probe_z); #endif @@ -2345,26 +2247,49 @@ static void clean_up_after_endstop_or_probe_move() { } #endif - // move down slowly to find bed - if (do_probe_move(-10 + (short_move ? 0 : -(Z_MAX_LENGTH)), Z_PROBE_SPEED_SLOW)) return NAN; + #if MULTIPLE_PROBING > 2 + float probes_total = 0; + for (uint8_t p = MULTIPLE_PROBING + 1; --p;) { + #endif + + // move down slowly to find bed + if (do_probe_move(-10, Z_PROBE_SPEED_SLOW)) return NAN; + + #if MULTIPLE_PROBING > 2 + probes_total += current_position[Z_AXIS]; + if (p > 1) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + } + #endif + + #if MULTIPLE_PROBING > 2 + + // Return the average value of all probes + return probes_total * (1.0 / (MULTIPLE_PROBING)); + + #elif MULTIPLE_PROBING == 2 + + const float z2 = current_position[Z_AXIS]; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("2nd Probe Z:", z2); + SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - z2); + } + #endif + + // Return a weighted average of the fast and slow probes + return (z2 * 3.0 + first_probe_z * 2.0) * 0.2; + + #else + + // Return the single probe result + return current_position[Z_AXIS]; + + #endif #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position); #endif - - // Debug: compare probe heights - #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) { - SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]); - SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]); - } - #endif - - return RAW_CURRENT_POSITION(Z) + zprobe_zoffset - #if ENABLED(DELTA) - + home_offset[Z_AXIS] // Account for delta height adjustment - #endif - ; } /** @@ -2376,46 +2301,44 @@ static void clean_up_after_endstop_or_probe_move() { * - Raise to the BETWEEN height * - Return the probed Z position */ - float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable=true) { + float probe_pt(const float &rx, const float &ry, const bool stow, const uint8_t verbose_level, const bool probe_relative=true) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { - SERIAL_ECHOPAIR(">>> probe_pt(", lx); - SERIAL_ECHOPAIR(", ", ly); + SERIAL_ECHOPAIR(">>> probe_pt(", LOGICAL_X_POSITION(rx)); + SERIAL_ECHOPAIR(", ", LOGICAL_Y_POSITION(ry)); SERIAL_ECHOPAIR(", ", stow ? "" : "no "); SERIAL_ECHOLNPGM("stow)"); DEBUG_POS("", current_position); } #endif - const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER); - - if (printable - ? !position_is_reachable_xy(nx, ny) - : !position_is_reachable_by_probe_xy(lx, ly) - ) return NAN; + // TODO: Adapt for SCARA, where the offset rotates + float nx = rx, ny = ry; + if (probe_relative) { + if (!position_is_reachable_by_probe(rx, ry)) return NAN; // The given position is in terms of the probe + nx -= (X_PROBE_OFFSET_FROM_EXTRUDER); // Get the nozzle position + ny -= (Y_PROBE_OFFSET_FROM_EXTRUDER); + } + else if (!position_is_reachable(nx, ny)) return NAN; // The given position is in terms of the nozzle + const float nz = + #if ENABLED(DELTA) + // Move below clip height or xy move will be aborted by do_blocking_move_to + min(current_position[Z_AXIS], delta_clip_start_height) + #else + current_position[Z_AXIS] + #endif + ; const float old_feedrate_mm_s = feedrate_mm_s; - - #if ENABLED(DELTA) - if (current_position[Z_AXIS] > delta_clip_start_height) - do_blocking_move_to_z(delta_clip_start_height); - #endif - - #if HAS_SOFTWARE_ENDSTOPS - // Store the status of the soft endstops and disable if we're probing a non-printable location - static bool enable_soft_endstops = soft_endstops_enabled; - if (!printable) soft_endstops_enabled = false; - #endif - feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S; - // Move the probe to the given XY - do_blocking_move_to_xy(nx, ny); + // Move the probe to the starting XYZ + do_blocking_move_to(nx, ny, nz); float measured_z = NAN; if (!DEPLOY_PROBE()) { - measured_z = run_z_probe(printable); + measured_z = run_z_probe() + zprobe_zoffset; if (!stow) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); @@ -2423,16 +2346,11 @@ static void clean_up_after_endstop_or_probe_move() { if (STOW_PROBE()) measured_z = NAN; } - #if HAS_SOFTWARE_ENDSTOPS - // Restore the soft endstop status - soft_endstops_enabled = enable_soft_endstops; - #endif - if (verbose_level > 2) { SERIAL_PROTOCOLPGM("Bed X: "); - SERIAL_PROTOCOL_F(lx, 3); + SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(rx), 3); SERIAL_PROTOCOLPGM(" Y: "); - SERIAL_PROTOCOL_F(ly, 3); + SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(ry), 3); SERIAL_PROTOCOLPGM(" Z: "); SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_EOL(); @@ -2460,7 +2378,7 @@ static void clean_up_after_endstop_or_probe_move() { bool leveling_is_valid() { return #if ENABLED(MESH_BED_LEVELING) - mbl.has_mesh() + mbl.has_mesh #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) !!bilinear_grid_spacing[X_AXIS] #elif ENABLED(AUTO_BED_LEVELING_UBL) @@ -2471,18 +2389,6 @@ static void clean_up_after_endstop_or_probe_move() { ; } - bool leveling_is_active() { - return - #if ENABLED(MESH_BED_LEVELING) - mbl.active() - #elif ENABLED(AUTO_BED_LEVELING_UBL) - ubl.state.active - #else - planner.abl_enabled - #endif - ; - } - /** * Turn bed leveling on or off, fixing the current * position as-needed. @@ -2498,7 +2404,7 @@ static void clean_up_after_endstop_or_probe_move() { constexpr bool can_change = true; #endif - if (can_change && enable != leveling_is_active()) { + if (can_change && enable != planner.leveling_active) { #if ENABLED(MESH_BED_LEVELING) @@ -2506,23 +2412,23 @@ static void clean_up_after_endstop_or_probe_move() { planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]); const bool enabling = enable && leveling_is_valid(); - mbl.set_active(enabling); + planner.leveling_active = enabling; if (enabling) planner.unapply_leveling(current_position); #elif ENABLED(AUTO_BED_LEVELING_UBL) #if PLANNER_LEVELING - if (ubl.state.active) { // leveling from on to off + if (planner.leveling_active) { // leveling from on to off // change unleveled current_position to physical current_position without moving steppers. planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]); - ubl.state.active = false; // disable only AFTER calling apply_leveling + planner.leveling_active = false; // disable only AFTER calling apply_leveling } else { // leveling from off to on - ubl.state.active = true; // enable BEFORE calling unapply_leveling, otherwise ignored + planner.leveling_active = true; // enable BEFORE calling unapply_leveling, otherwise ignored // change physical current_position to unleveled current_position without moving steppers. planner.unapply_leveling(current_position); } #else - ubl.state.active = enable; // just flip the bit, current_position will be wrong until next move. + planner.leveling_active = enable; // just flip the bit, current_position will be wrong until next move. #endif #else // ABL @@ -2534,7 +2440,7 @@ static void clean_up_after_endstop_or_probe_move() { #endif // Enable or disable leveling compensation in the planner - planner.abl_enabled = enable; + planner.leveling_active = enable; if (!enable) // When disabling just get the current position from the steppers. @@ -2551,31 +2457,31 @@ static void clean_up_after_endstop_or_probe_move() { // so compensation will give the right stepper counts. planner.unapply_leveling(current_position); + SYNC_PLAN_POSITION_KINEMATIC(); + #endif // ABL } } #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void set_z_fade_height(const float zfh) { + void set_z_fade_height(const float zfh, const bool do_report/*=true*/) { - const bool level_active = leveling_is_active(); + if (planner.z_fade_height == zfh) return; // do nothing if no change + + const bool level_active = planner.leveling_active; #if ENABLED(AUTO_BED_LEVELING_UBL) + if (level_active) set_bed_leveling_enabled(false); // turn off before changing fade height for proper apply/unapply leveling to maintain current_position + #endif - if (level_active) - set_bed_leveling_enabled(false); // turn off before changing fade height for proper apply/unapply leveling to maintain current_position - planner.z_fade_height = zfh; - planner.inverse_z_fade_height = RECIPROCAL(zfh); - if (level_active) + planner.set_z_fade_height(zfh); + + if (level_active) { + const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; + #if ENABLED(AUTO_BED_LEVELING_UBL) set_bed_leveling_enabled(true); // turn back on after changing fade height - - #else - - planner.z_fade_height = zfh; - planner.inverse_z_fade_height = RECIPROCAL(zfh); - - if (level_active) { + #else set_current_from_steppers_for_axis( #if ABL_PLANAR ALL_AXES @@ -2583,8 +2489,11 @@ static void clean_up_after_endstop_or_probe_move() { Z_AXIS #endif ); - } - #endif + SYNC_PLAN_POSITION_KINEMATIC(); + #endif + if (do_report && memcmp(oldpos, current_position, sizeof(oldpos))) + report_current_position(); + } } #endif // LEVELING_FADE_HEIGHT @@ -2597,7 +2506,7 @@ static void clean_up_after_endstop_or_probe_move() { #if ENABLED(MESH_BED_LEVELING) if (leveling_is_valid()) { mbl.reset(); - mbl.set_has_mesh(false); + mbl.has_mesh = false; } #else #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -2929,7 +2838,7 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa if (axis == Z_AXIS) probing_pause(true); #endif - // Tell the planner we're at Z=0 + // Tell the planner the axis is at 0 current_position[axis] = 0; #if IS_SCARA @@ -2970,7 +2879,8 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa * spreadCycle and stealthChop are mutually exclusive. */ #if ENABLED(SENSORLESS_HOMING) - void tmc2130_sensorless_homing(TMC2130Stepper &st, bool enable=true) { + template + void tmc_sensorless_homing(TMC &st, bool enable=true) { #if ENABLED(STEALTHCHOP) if (enable) { st.coolstep_min_speed(1024UL * 1024UL - 1UL); @@ -3029,18 +2939,24 @@ static void homeaxis(const AxisEnum axis) { if (axis == Z_AXIS && DEPLOY_PROBE()) return; #endif - // Set a flag for Z motor locking + // Set flags for X, Y, Z motor locking + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) stepper.set_homing_flag_x(true); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) stepper.set_homing_flag_y(true); + #endif #if ENABLED(Z_DUAL_ENDSTOPS) - if (axis == Z_AXIS) stepper.set_homing_flag(true); + if (axis == Z_AXIS) stepper.set_homing_flag_z(true); #endif // Disable stealthChop if used. Enable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) #if ENABLED(X_IS_TMC2130) - if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX); + if (axis == X_AXIS) tmc_sensorless_homing(stepperX); #endif #if ENABLED(Y_IS_TMC2130) - if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY); + if (axis == Y_AXIS) tmc_sensorless_homing(stepperY); #endif #endif @@ -3073,25 +2989,41 @@ static void homeaxis(const AxisEnum axis) { do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); } - #if ENABLED(Z_DUAL_ENDSTOPS) - if (axis == Z_AXIS) { - float adj = FABS(z_endstop_adj); - bool lockZ1; - if (axis_home_dir > 0) { - adj = -adj; - lockZ1 = (z_endstop_adj > 0); + /** + * Home axes that have dual endstops... differently + */ + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const bool lock_x1 = pos_dir ? (x_endstop_adj > 0) : (x_endstop_adj < 0); + const float adj = FABS(x_endstop_adj); + if (lock_x1) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + if (lock_x1) stepper.set_x_lock(false); else stepper.set_x2_lock(false); + stepper.set_homing_flag_x(false); } - else - lockZ1 = (z_endstop_adj < 0); - - if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); - - // Move to the adjusted endstop height - do_homing_move(axis, adj); - - if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); - stepper.set_homing_flag(false); - } // Z_AXIS + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const bool lock_y1 = pos_dir ? (y_endstop_adj > 0) : (y_endstop_adj < 0); + const float adj = FABS(y_endstop_adj); + if (lock_y1) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + if (lock_y1) stepper.set_y_lock(false); else stepper.set_y2_lock(false); + stepper.set_homing_flag_y(false); + } + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) { + const bool lock_z1 = pos_dir ? (z_endstop_adj > 0) : (z_endstop_adj < 0); + const float adj = FABS(z_endstop_adj); + if (lock_z1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + if (lock_z1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); + stepper.set_homing_flag_z(false); + } + #endif #endif #if IS_SCARA @@ -3105,12 +3037,12 @@ static void homeaxis(const AxisEnum axis) { // so here it re-homes each tower in turn. // Delta homing treats the axes as normal linear axes. - // retrace by the amount specified in endstop_adj + additional 0.1mm in order to have minimum steps - if (endstop_adj[axis] * Z_HOME_DIR <= 0) { + // retrace by the amount specified in delta_endstop_adj + additional 0.1mm in order to have minimum steps + if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) { #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("endstop_adj:"); + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("delta_endstop_adj:"); #endif - do_homing_move(axis, endstop_adj[axis] - 0.1 * Z_HOME_DIR); + do_homing_move(axis, delta_endstop_adj[axis] - 0.1 * Z_HOME_DIR); } #else @@ -3131,10 +3063,10 @@ static void homeaxis(const AxisEnum axis) { // Re-enable stealthChop if used. Disable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) #if ENABLED(X_IS_TMC2130) - if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX, false); + if (axis == X_AXIS) tmc_sensorless_homing(stepperX, false); #endif #if ENABLED(Y_IS_TMC2130) - if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY, false); + if (axis == Y_AXIS) tmc_sensorless_homing(stepperY, false); #endif #endif @@ -3174,16 +3106,20 @@ static void homeaxis(const AxisEnum axis) { #endif ) { - static float hop_height, // Remember where the Z height started - hop_amount = 0.0; // Total amount lifted, for use in recover + static float hop_amount = 0.0; // Total amount lifted, for use in recover - // Simply never allow two retracts or recovers in a row + // Prevent two retracts or recovers in a row if (retracted[active_extruder] == retracting) return; - #if EXTRUDERS < 2 - bool swapping = false; + // Prevent two swap-retract or recovers in a row + #if EXTRUDERS > 1 + // Allow G10 S1 only after G10 + if (swapping && retracted_swap[active_extruder] == retracting) return; + // G11 priority to recover the long retract if activated + if (!retracting) swapping = retracted_swap[active_extruder]; + #else + const bool swapping = false; #endif - if (!retracting) swapping = retracted_swap[active_extruder]; /* // debugging SERIAL_ECHOLNPAIR("retracting ", retracting); @@ -3200,64 +3136,55 @@ static void homeaxis(const AxisEnum axis) { //*/ const bool has_zhop = retract_zlift > 0.01; // Is there a hop set? - const float old_feedrate_mm_s = feedrate_mm_s; - const int16_t old_flow = flow_percentage[active_extruder]; - - // Don't apply flow multiplication to retract/recover - flow_percentage[active_extruder] = 100; // The current position will be the destination for E and Z moves - set_destination_to_current(); + set_destination_from_current(); + stepper.synchronize(); // Wait for buffered moves to complete - stepper.synchronize(); // Wait for all moves to finish + const float renormalize = 1.0 / planner.e_factor[active_extruder]; if (retracting) { - // Remember the Z height since G-code may include its own Z-hop - // For best results turn off Z hop if G-code already includes it - hop_height = destination[Z_AXIS]; - // Retract by moving from a faux E position back to the current E position feedrate_mm_s = retract_feedrate_mm_s; - current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) / volumetric_multiplier[active_extruder]; + current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize; sync_plan_position_e(); prepare_move_to_destination(); // Is a Z hop set, and has the hop not yet been done? - if (has_zhop) { - hop_amount += retract_zlift; // Carriage is raised for retraction hop - current_position[Z_AXIS] -= retract_zlift; // Pretend current pos is lower. Next move raises Z. - SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position - prepare_move_to_destination(); // Raise up to the old current pos + if (has_zhop && !hop_amount) { + hop_amount += retract_zlift; // Carriage is raised for retraction hop + feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max + current_position[Z_AXIS] -= retract_zlift; // Pretend current pos is lower. Next move raises Z. + SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position + prepare_move_to_destination(); // Raise up to the old current pos + feedrate_mm_s = retract_feedrate_mm_s; // Restore feedrate } } else { // If a hop was done and Z hasn't changed, undo the Z hop - if (hop_amount && NEAR(hop_height, destination[Z_AXIS])) { - current_position[Z_AXIS] += hop_amount; // Pretend current pos is higher. Next move lowers Z. - SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position - prepare_move_to_destination(); // Lower to the old current pos - hop_amount = 0.0; + if (hop_amount) { + current_position[Z_AXIS] += retract_zlift; // Pretend current pos is lower. Next move raises Z. + SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position + feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max + prepare_move_to_destination(); // Raise up to the old current pos + hop_amount = 0.0; // Clear hop } // A retract multiplier has been added here to get faster swap recovery feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s; const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length; - current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder]; + current_position[E_AXIS] -= move_e * renormalize; sync_plan_position_e(); - - prepare_move_to_destination(); // Recover E + prepare_move_to_destination(); // Recover E } - // Restore flow and feedrate - flow_percentage[active_extruder] = old_flow; - feedrate_mm_s = old_feedrate_mm_s; + feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate - // The active extruder is now retracted or recovered - retracted[active_extruder] = retracting; + retracted[active_extruder] = retracting; // Active extruder now retracted / recovered - // If swap retract/recover then update the retracted_swap flag too + // If swap retract/recover update the retracted_swap flag too #if EXTRUDERS > 1 if (swapping) retracted_swap[active_extruder] = retracting; #endif @@ -3276,7 +3203,7 @@ static void homeaxis(const AxisEnum axis) { SERIAL_ECHOLNPAIR("hop_amount ", hop_amount); //*/ - } // retract() + } #endif // FWRETRACT @@ -3334,8 +3261,10 @@ static void homeaxis(const AxisEnum axis) { */ void gcode_get_destination() { LOOP_XYZE(i) { - if (parser.seen(axis_codes[i])) - destination[i] = parser.value_axis_units((AxisEnum)i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0); + if (parser.seen(axis_codes[i])) { + const float v = parser.value_axis_units((AxisEnum)i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0); + destination[i] = i == E_AXIS ? v : LOGICAL_TO_NATIVE(v, i); + } else destination[i] = current_position[i]; } @@ -3392,6 +3321,12 @@ void gcode_get_destination() { ***************** GCode Handlers ***************** **************************************************/ +#if ENABLED(NO_MOTION_BEFORE_HOMING) + #define G0_G1_CONDITION !axis_unhomed_error(parser.seen('X'), parser.seen('Y'), parser.seen('Z')) +#else + #define G0_G1_CONDITION true +#endif + /** * G0, G1: Coordinated movement of X Y Z E axes */ @@ -3400,11 +3335,7 @@ inline void gcode_G0_G1( bool fast_move=false #endif ) { - #if ENABLED(NO_MOTION_BEFORE_HOMING) - if (axis_unhomed_error()) return; - #endif - - if (IsRunning()) { + if (IsRunning() && G0_G1_CONDITION) { gcode_get_destination(); // For X Y Z E F #if ENABLED(FWRETRACT) @@ -3427,6 +3358,18 @@ inline void gcode_G0_G1( #else prepare_move_to_destination(); #endif + + #if ENABLED(NANODLP_Z_SYNC) + #if ENABLED(NANODLP_ALL_AXIS) + #define _MOVE_SYNC true // For any move wait and output sync message + #else + #define _MOVE_SYNC parser.seenval('Z') // Only for Z move + #endif + if (_MOVE_SYNC) { + stepper.synchronize(); + SERIAL_ECHOLNPGM(MSG_Z_MOVE_COMP); + } + #endif } } @@ -3458,7 +3401,7 @@ inline void gcode_G0_G1( */ #if ENABLED(ARC_SUPPORT) - inline void gcode_G2_G3(bool clockwise) { + inline void gcode_G2_G3(const bool clockwise) { #if ENABLED(NO_MOTION_BEFORE_HOMING) if (axis_unhomed_error()) return; #endif @@ -3541,6 +3484,9 @@ inline void gcode_G4() { if (parser.seenval('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait stepper.synchronize(); + #if ENABLED(NANODLP_Z_SYNC) + SERIAL_ECHOLNPGM(MSG_Z_MOVE_COMP); + #endif if (!lcd_hasstatus()) LCD_MESSAGEPGM(MSG_DWELL); @@ -3632,10 +3578,19 @@ inline void gcode_G4() { #if ENABLED(CNC_WORKSPACE_PLANES) - void report_workspace_plane() { + inline void report_workspace_plane() { SERIAL_ECHO_START(); SERIAL_ECHOPGM("Workspace Plane "); - serialprintPGM(workspace_plane == PLANE_YZ ? PSTR("YZ\n") : workspace_plane == PLANE_ZX ? PSTR("ZX\n") : PSTR("XY\n")); + serialprintPGM( + workspace_plane == PLANE_YZ ? PSTR("YZ\n") : + workspace_plane == PLANE_ZX ? PSTR("ZX\n") : + PSTR("XY\n") + ); + } + + inline void set_workspace_plane(const WorkspacePlane plane) { + workspace_plane = plane; + if (DEBUGGING(INFO)) report_workspace_plane(); } /** @@ -3643,12 +3598,76 @@ inline void gcode_G4() { * G18: Select Plane ZX * G19: Select Plane YZ */ - inline void gcode_G17() { workspace_plane = PLANE_XY; } - inline void gcode_G18() { workspace_plane = PLANE_ZX; } - inline void gcode_G19() { workspace_plane = PLANE_YZ; } + inline void gcode_G17() { set_workspace_plane(PLANE_XY); } + inline void gcode_G18() { set_workspace_plane(PLANE_ZX); } + inline void gcode_G19() { set_workspace_plane(PLANE_YZ); } #endif // CNC_WORKSPACE_PLANES +#if ENABLED(CNC_COORDINATE_SYSTEMS) + + /** + * Select a coordinate system and update the workspace offset. + * System index -1 is used to specify machine-native. + */ + bool select_coordinate_system(const int8_t _new) { + if (active_coordinate_system == _new) return false; + float old_offset[XYZ] = { 0 }, new_offset[XYZ] = { 0 }; + if (WITHIN(active_coordinate_system, 0, MAX_COORDINATE_SYSTEMS - 1)) + COPY(old_offset, coordinate_system[active_coordinate_system]); + if (WITHIN(_new, 0, MAX_COORDINATE_SYSTEMS - 1)) + COPY(new_offset, coordinate_system[_new]); + active_coordinate_system = _new; + LOOP_XYZ(i) { + const float diff = new_offset[i] - old_offset[i]; + if (diff) { + position_shift[i] += diff; + update_software_endstops((AxisEnum)i); + } + } + return true; + } + + /** + * In CNC G-code G53 is like a modifier + * It precedes a movement command (or other modifiers) on the same line. + * This is the first command to use parser.chain() to make this possible. + */ + inline void gcode_G53() { + // If this command has more following... + if (parser.chain()) { + const int8_t _system = active_coordinate_system; + active_coordinate_system = -1; + process_parsed_command(); + active_coordinate_system = _system; + } + } + + /** + * G54-G59.3: Select a new workspace + * + * A workspace is an XYZ offset to the machine native space. + * All workspaces default to 0,0,0 at start, or with EEPROM + * support they may be restored from a previous session. + * + * G92 is used to set the current workspace's offset. + */ + inline void gcode_G54_59(uint8_t subcode=0) { + const int8_t _space = parser.codenum - 54 + subcode; + if (select_coordinate_system(_space)) { + SERIAL_PROTOCOLLNPAIR("Select workspace ", _space); + report_current_position(); + } + } + FORCE_INLINE void gcode_G54() { gcode_G54_59(); } + FORCE_INLINE void gcode_G55() { gcode_G54_59(); } + FORCE_INLINE void gcode_G56() { gcode_G54_59(); } + FORCE_INLINE void gcode_G57() { gcode_G54_59(); } + FORCE_INLINE void gcode_G58() { gcode_G54_59(); } + FORCE_INLINE void gcode_G59() { gcode_G54_59(parser.subcode); } + +#endif + #if ENABLED(INCH_MODE_SUPPORT) /** * G20: Set input mode to inches @@ -3771,7 +3790,7 @@ inline void gcode_G4() { #elif ENABLED(AUTO_BED_LEVELING_UBL) SERIAL_ECHOPGM("UBL"); #endif - if (leveling_is_active()) { + if (planner.leveling_active) { SERIAL_ECHOLNPGM(" (enabled)"); #if ABL_PLANAR const float diff[XYZ] = { @@ -3802,11 +3821,11 @@ inline void gcode_G4() { #elif ENABLED(MESH_BED_LEVELING) SERIAL_ECHOPGM("Mesh Bed Leveling"); - if (leveling_is_active()) { - float lz = current_position[Z_AXIS]; - planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], lz); + if (planner.leveling_active) { + float rz = current_position[Z_AXIS]; + planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], rz); SERIAL_ECHOLNPGM(" (enabled)"); - SERIAL_ECHOPAIR("MBL Adjustment Z", lz); + SERIAL_ECHOPAIR("MBL Adjustment Z", rz); } else SERIAL_ECHOPGM(" (disabled)"); @@ -3833,14 +3852,13 @@ inline void gcode_G4() { sync_plan_position(); // Move all carriages together linearly until an endstop is hit. - current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (DELTA_HEIGHT + home_offset[Z_AXIS] + 10); + current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (delta_height + 10); feedrate_mm_s = homing_feedrate(X_AXIS); - line_to_current_position(); + buffer_line_to_current_position(); stepper.synchronize(); // If an endstop was not hit, then damage can occur if homing is continued. - // This can occur if the delta height (DELTA_HEIGHT + home_offset[Z_AXIS]) is - // not set correctly. + // This can occur if the delta height not set correctly. if (!(Endstops::endstop_hit_bits & (_BV(X_MAX) | _BV(Y_MAX) | _BV(Z_MAX)))) { LCD_MESSAGEPGM(MSG_ERR_HOMING_FAILED); SERIAL_ERROR_START(); @@ -3894,8 +3912,8 @@ inline void gcode_G4() { /** * Move the Z probe (or just the nozzle) to the safe homing point */ - destination[X_AXIS] = LOGICAL_X_POSITION(Z_SAFE_HOMING_X_POINT); - destination[Y_AXIS] = LOGICAL_Y_POSITION(Z_SAFE_HOMING_Y_POINT); + destination[X_AXIS] = Z_SAFE_HOMING_X_POINT; + destination[Y_AXIS] = Z_SAFE_HOMING_Y_POINT; destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height #if HOMING_Z_WITH_PROBE @@ -3903,7 +3921,7 @@ inline void gcode_G4() { destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; #endif - if (position_is_reachable_xy(destination[X_AXIS], destination[Y_AXIS])) { + if (position_is_reachable(destination[X_AXIS], destination[Y_AXIS])) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination); @@ -3971,7 +3989,7 @@ inline void gcode_G28(const bool always_home_all) { // Disable the leveling matrix before homing #if HAS_LEVELING #if ENABLED(AUTO_BED_LEVELING_UBL) - const bool ubl_state_at_entry = leveling_is_active(); + const bool ubl_state_at_entry = planner.leveling_active; #endif set_bed_leveling_enabled(false); #endif @@ -4008,7 +4026,7 @@ inline void gcode_G28(const bool always_home_all) { homeZ = always_home_all || parser.seen('Z'), home_all = (!homeX && !homeY && !homeZ) || (homeX && homeY && homeZ); - set_destination_to_current(); + set_destination_from_current(); #if Z_HOME_DIR > 0 // If homing away from BED do Z first @@ -4019,24 +4037,22 @@ inline void gcode_G28(const bool always_home_all) { #endif } - #else - - if (home_all || homeX || homeY) { - // Raise Z before homing any other axes and z is not already high enough (never lower z) - destination[Z_AXIS] = LOGICAL_Z_POSITION(Z_HOMING_HEIGHT); - if (destination[Z_AXIS] > current_position[Z_AXIS]) { - - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) - SERIAL_ECHOLNPAIR("Raise Z (before homing) to ", destination[Z_AXIS]); - #endif - - do_blocking_move_to_z(destination[Z_AXIS]); - } - } - #endif + if (home_all || homeX || homeY) { + // Raise Z before homing any other axes and z is not already high enough (never lower z) + destination[Z_AXIS] = Z_HOMING_HEIGHT; + if (destination[Z_AXIS] > current_position[Z_AXIS]) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPAIR("Raise Z (before homing) to ", destination[Z_AXIS]); + #endif + + do_blocking_move_to_z(destination[Z_AXIS]); + } + } + #if ENABLED(QUICK_HOME) if (home_all || (homeX && homeY)) quick_home_xy(); @@ -4065,7 +4081,7 @@ inline void gcode_G28(const bool always_home_all) { HOMEAXIS(X); // Remember this extruder's position for later tool change - inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]); + inactive_extruder_x_pos = current_position[X_AXIS]; // Home the 1st (left) extruder active_extruder = 0; @@ -4130,19 +4146,28 @@ inline void gcode_G28(const bool always_home_all) { // Restore the active tool after homing #if HOTENDS > 1 - tool_change(old_tool_index, 0, - #if ENABLED(PARKING_EXTRUDER) - false // fetch the previous toolhead - #else - true - #endif - ); + #if ENABLED(PARKING_EXTRUDER) + #define NO_FETCH false // fetch the previous toolhead + #else + #define NO_FETCH true + #endif + tool_change(old_tool_index, 0, NO_FETCH); #endif lcd_refresh(); report_current_position(); + #if ENABLED(NANODLP_Z_SYNC) + #if ENABLED(NANODLP_ALL_AXIS) + #define _HOME_SYNC true // For any axis, output sync text. + #else + #define _HOME_SYNC (home_all || homeZ) // Only for Z-axis + #endif + if (_HOME_SYNC) + SERIAL_ECHOLNPGM(MSG_Z_MOVE_COMP); + #endif + #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G28"); #endif @@ -4162,34 +4187,26 @@ void home_all_axes() { gcode_G28(true); } #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) - #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + #if ENABLED(LCD_BED_LEVELING) extern bool lcd_wait_for_move; + #else + constexpr bool lcd_wait_for_move = false; #endif - inline void _manual_goto_xy(const float &x, const float &y) { - const float old_feedrate_mm_s = feedrate_mm_s; + inline void _manual_goto_xy(const float &rx, const float &ry) { + #if MANUAL_PROBE_HEIGHT > 0 const float prev_z = current_position[Z_AXIS]; - feedrate_mm_s = homing_feedrate(Z_AXIS); - current_position[Z_AXIS] = LOGICAL_Z_POSITION(MANUAL_PROBE_HEIGHT); - line_to_current_position(); + do_blocking_move_to(rx, ry, MANUAL_PROBE_HEIGHT); + do_blocking_move_to_z(prev_z); + #else + do_blocking_move_to_xy(rx, ry); #endif - feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); - current_position[X_AXIS] = LOGICAL_X_POSITION(x); - current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); - line_to_current_position(); + current_position[X_AXIS] = rx; + current_position[Y_AXIS] = ry; - #if MANUAL_PROBE_HEIGHT > 0 - feedrate_mm_s = homing_feedrate(Z_AXIS); - current_position[Z_AXIS] = prev_z; // move back to the previous Z. - line_to_current_position(); - #endif - - feedrate_mm_s = old_feedrate_mm_s; - stepper.synchronize(); - - #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + #if ENABLED(LCD_BED_LEVELING) lcd_wait_for_move = false; #endif } @@ -4210,18 +4227,6 @@ void home_all_axes() { gcode_G28(true); } ); } - void mesh_probing_done() { - mbl.set_has_mesh(true); - home_all_axes(); - set_bed_leveling_enabled(true); - #if ENABLED(MESH_G28_REST_ORIGIN) - current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS); - set_destination_to_current(); - line_to_destination(homing_feedrate(Z_AXIS)); - stepper.synchronize(); - #endif - } - /** * G29: Mesh-based Z probe, probes a grid and produces a * mesh to compensate for variable bed height @@ -4261,7 +4266,7 @@ void home_all_axes() { gcode_G28(true); } switch (state) { case MeshReport: if (leveling_is_valid()) { - SERIAL_PROTOCOLLNPAIR("State: ", leveling_is_active() ? MSG_ON : MSG_OFF); + SERIAL_PROTOCOLLNPAIR("State: ", planner.leveling_active ? MSG_ON : MSG_OFF); mbl_mesh_report(); } else @@ -4271,7 +4276,7 @@ void home_all_axes() { gcode_G28(true); } case MeshStart: mbl.reset(); mbl_probe_index = 0; - enqueue_and_echo_commands_P(PSTR("G28\nG29 S2")); + enqueue_and_echo_commands_P(lcd_wait_for_move ? PSTR("G29 S2") : PSTR("G28\nG29 S2")); break; case MeshNext: @@ -4308,8 +4313,8 @@ void home_all_axes() { gcode_G28(true); } } else { // One last "return to the bed" (as originally coded) at completion - current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; - line_to_current_position(); + current_position[Z_AXIS] = Z_MIN_POS + MANUAL_PROBE_HEIGHT; + buffer_line_to_current_position(); stepper.synchronize(); // After recording the last point, activate home and activate @@ -4317,7 +4322,21 @@ void home_all_axes() { gcode_G28(true); } SERIAL_PROTOCOLLNPGM("Mesh probing done."); BUZZ(100, 659); BUZZ(100, 698); - mesh_probing_done(); + mbl.has_mesh = true; + + home_all_axes(); + set_bed_leveling_enabled(true); + + #if ENABLED(MESH_G28_REST_ORIGIN) + current_position[Z_AXIS] = Z_MIN_POS; + set_destination_from_current(); + buffer_line_to_destination(homing_feedrate(Z_AXIS)); + stepper.synchronize(); + #endif + + #if ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif } break; @@ -4346,9 +4365,8 @@ void home_all_axes() { gcode_G28(true); } return; } - if (parser.seenval('Z')) { + if (parser.seenval('Z')) mbl.z_values[px][py] = parser.value_linear_units(); - } else { SERIAL_CHAR('Z'); echo_not_entered(); return; @@ -4356,9 +4374,8 @@ void home_all_axes() { gcode_G28(true); } break; case MeshSetZOffset: - if (parser.seenval('Z')) { + if (parser.seenval('Z')) mbl.z_offset = parser.value_linear_units(); - } else { SERIAL_CHAR('Z'); echo_not_entered(); return; @@ -4371,10 +4388,15 @@ void home_all_axes() { gcode_G28(true); } } // switch(state) + if (state == MeshStart || state == MeshNext) { + SERIAL_PROTOCOLPAIR("MBL G29 point ", min(mbl_probe_index, GRID_MAX_POINTS)); + SERIAL_PROTOCOLLNPAIR(" of ", int(GRID_MAX_POINTS)); + } + report_current_position(); } -#elif HAS_ABL && DISABLED(AUTO_BED_LEVELING_UBL) +#elif OLDSCHOOL_ABL #if ABL_GRID #if ENABLED(PROBE_Y_FIRST) @@ -4580,7 +4602,7 @@ void home_all_axes() { gcode_G28(true); } abl_probe_index = -1; #endif - abl_should_enable = leveling_is_active(); + abl_should_enable = planner.leveling_active; #if ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -4591,32 +4613,33 @@ void home_all_axes() { gcode_G28(true); } return; } - const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z)); - if (!WITHIN(z, -10, 10)) { + const float rz = parser.seenval('Z') ? RAW_Z_POSITION(parser.value_linear_units()) : current_position[Z_AXIS]; + if (!WITHIN(rz, -10, 10)) { SERIAL_ERROR_START(); SERIAL_ERRORLNPGM("Bad Z value"); return; } - const float x = parser.floatval('X', NAN), - y = parser.floatval('Y', NAN); + const float rx = RAW_X_POSITION(parser.linearval('X', NAN)), + ry = RAW_Y_POSITION(parser.linearval('Y', NAN)); int8_t i = parser.byteval('I', -1), j = parser.byteval('J', -1); - if (!isnan(x) && !isnan(y)) { + if (!isnan(rx) && !isnan(ry)) { // Get nearest i / j from x / y - i = (x - LOGICAL_X_POSITION(bilinear_start[X_AXIS]) + 0.5 * xGridSpacing) / xGridSpacing; - j = (y - LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + 0.5 * yGridSpacing) / yGridSpacing; + i = (rx - bilinear_start[X_AXIS] + 0.5 * xGridSpacing) / xGridSpacing; + j = (ry - bilinear_start[Y_AXIS] + 0.5 * yGridSpacing) / yGridSpacing; i = constrain(i, 0, GRID_MAX_POINTS_X - 1); j = constrain(j, 0, GRID_MAX_POINTS_Y - 1); } if (WITHIN(i, 0, GRID_MAX_POINTS_X - 1) && WITHIN(j, 0, GRID_MAX_POINTS_Y)) { set_bed_leveling_enabled(false); - z_values[i][j] = z; + z_values[i][j] = rz; #if ENABLED(ABL_BILINEAR_SUBDIVISION) bed_level_virt_interpolate(); #endif set_bed_leveling_enabled(abl_should_enable); + report_current_position(); } return; } // parser.seen('W') @@ -4672,36 +4695,36 @@ void home_all_axes() { gcode_G28(true); } xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED)); - left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION)); - right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION)); - front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION)); - back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION)); + left_probe_bed_position = parser.seenval('L') ? (int)RAW_X_POSITION(parser.value_linear_units()) : LEFT_PROBE_BED_POSITION; + right_probe_bed_position = parser.seenval('R') ? (int)RAW_X_POSITION(parser.value_linear_units()) : RIGHT_PROBE_BED_POSITION; + front_probe_bed_position = parser.seenval('F') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : FRONT_PROBE_BED_POSITION; + back_probe_bed_position = parser.seenval('B') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : BACK_PROBE_BED_POSITION; - const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X), + const bool left_out_l = left_probe_bed_position < MIN_PROBE_X, left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE), - right_out_r = right_probe_bed_position > LOGICAL_X_POSITION(MAX_PROBE_X), + right_out_r = right_probe_bed_position > MAX_PROBE_X, right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE, - front_out_f = front_probe_bed_position < LOGICAL_Y_POSITION(MIN_PROBE_Y), + front_out_f = front_probe_bed_position < MIN_PROBE_Y, front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE), - back_out_b = back_probe_bed_position > LOGICAL_Y_POSITION(MAX_PROBE_Y), + back_out_b = back_probe_bed_position > MAX_PROBE_Y, back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE; if (left_out || right_out || front_out || back_out) { if (left_out) { out_of_range_error(PSTR("(L)eft")); - left_probe_bed_position = left_out_l ? LOGICAL_X_POSITION(MIN_PROBE_X) : right_probe_bed_position - (MIN_PROBE_EDGE); + left_probe_bed_position = left_out_l ? MIN_PROBE_X : right_probe_bed_position - (MIN_PROBE_EDGE); } if (right_out) { out_of_range_error(PSTR("(R)ight")); - right_probe_bed_position = right_out_r ? LOGICAL_Y_POSITION(MAX_PROBE_X) : left_probe_bed_position + MIN_PROBE_EDGE; + right_probe_bed_position = right_out_r ? MAX_PROBE_X : left_probe_bed_position + MIN_PROBE_EDGE; } if (front_out) { out_of_range_error(PSTR("(F)ront")); - front_probe_bed_position = front_out_f ? LOGICAL_Y_POSITION(MIN_PROBE_Y) : back_probe_bed_position - (MIN_PROBE_EDGE); + front_probe_bed_position = front_out_f ? MIN_PROBE_Y : back_probe_bed_position - (MIN_PROBE_EDGE); } if (back_out) { out_of_range_error(PSTR("(B)ack")); - back_probe_bed_position = back_out_b ? LOGICAL_Y_POSITION(MAX_PROBE_Y) : front_probe_bed_position + MIN_PROBE_EDGE; + back_probe_bed_position = back_out_b ? MAX_PROBE_Y : front_probe_bed_position + MIN_PROBE_EDGE; } return; } @@ -4720,7 +4743,7 @@ void home_all_axes() { gcode_G28(true); } stepper.synchronize(); // Disable auto bed leveling during G29 - planner.abl_enabled = false; + planner.leveling_active = false; if (!dryrun) { // Re-orient the current position without leveling @@ -4734,7 +4757,7 @@ void home_all_axes() { gcode_G28(true); } #if HAS_BED_PROBE // Deploy the probe. Probe will raise if needed. if (DEPLOY_PROBE()) { - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; return; } #endif @@ -4748,12 +4771,12 @@ void home_all_axes() { gcode_G28(true); } #endif if ( xGridSpacing != bilinear_grid_spacing[X_AXIS] || yGridSpacing != bilinear_grid_spacing[Y_AXIS] - || left_probe_bed_position != LOGICAL_X_POSITION(bilinear_start[X_AXIS]) - || front_probe_bed_position != LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + || left_probe_bed_position != bilinear_start[X_AXIS] + || front_probe_bed_position != bilinear_start[Y_AXIS] ) { if (dryrun) { // Before reset bed level, re-enable to correct the position - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; } // Reset grid to 0.0 or "not probed". (Also disables ABL) reset_bed_level(); @@ -4761,8 +4784,8 @@ void home_all_axes() { gcode_G28(true); } // Initialize a grid with the given dimensions bilinear_grid_spacing[X_AXIS] = xGridSpacing; bilinear_grid_spacing[Y_AXIS] = yGridSpacing; - bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position); - bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position); + bilinear_start[X_AXIS] = left_probe_bed_position; + bilinear_start[Y_AXIS] = front_probe_bed_position; // Can't re-enable (on error) until the new grid is written abl_should_enable = false; @@ -4798,7 +4821,7 @@ void home_all_axes() { gcode_G28(true); } #if HAS_SOFTWARE_ENDSTOPS soft_endstops_enabled = enable_soft_endstops; #endif - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; g29_in_progress = false; #if ENABLED(LCD_BED_LEVELING) lcd_wait_for_move = false; @@ -4887,7 +4910,7 @@ void home_all_axes() { gcode_G28(true); } #endif // Keep looping till a reachable point is found - if (position_is_reachable_xy(xProbe, yProbe)) break; + if (position_is_reachable(xProbe, yProbe)) break; ++abl_probe_index; } @@ -4917,8 +4940,8 @@ void home_all_axes() { gcode_G28(true); } // Probe at 3 arbitrary points if (abl_probe_index < 3) { - xProbe = LOGICAL_X_POSITION(points[abl_probe_index].x); - yProbe = LOGICAL_Y_POSITION(points[abl_probe_index].y); + xProbe = points[abl_probe_index].x; + yProbe = points[abl_probe_index].y; #if HAS_SOFTWARE_ENDSTOPS // Disable software endstops to allow manual adjustment // If G29 is not completed, they will not be re-enabled @@ -4960,6 +4983,8 @@ void home_all_axes() { gcode_G28(true); } bool zig = PR_OUTER_END & 1; // Always end at RIGHT and BACK_PROBE_BED_POSITION + measured_z = 0; + // Outer loop is Y with PROBE_Y_FIRST disabled for (uint8_t PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_END && !isnan(measured_z); PR_OUTER_VAR++) { @@ -4993,13 +5018,13 @@ void home_all_axes() { gcode_G28(true); } #if IS_KINEMATIC // Avoid probing outside the round or hexagonal area - if (!position_is_reachable_by_probe_xy(xProbe, yProbe)) continue; + if (!position_is_reachable_by_probe(xProbe, yProbe)) continue; #endif measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); if (isnan(measured_z)) { - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; break; } @@ -5031,11 +5056,11 @@ void home_all_axes() { gcode_G28(true); } for (uint8_t i = 0; i < 3; ++i) { // Retain the last probe position - xProbe = LOGICAL_X_POSITION(points[i].x); - yProbe = LOGICAL_Y_POSITION(points[i].y); + xProbe = points[i].x; + yProbe = points[i].y; measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); if (isnan(measured_z)) { - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; break; } points[i].z = measured_z; @@ -5058,7 +5083,7 @@ void home_all_axes() { gcode_G28(true); } // Raise to _Z_CLEARANCE_DEPLOY_PROBE. Stow the probe. if (STOW_PROBE()) { - planner.abl_enabled = abl_should_enable; + planner.leveling_active = abl_should_enable; measured_z = NAN; } } @@ -5226,9 +5251,9 @@ void home_all_axes() { gcode_G28(true); } float converted[XYZ]; COPY(converted, current_position); - planner.abl_enabled = true; + planner.leveling_active = true; planner.unapply_leveling(converted); // use conversion machinery - planner.abl_enabled = false; + planner.leveling_active = false; // Use the last measured distance to the bed, if possible if ( NEAR(current_position[X_AXIS], xProbe - (X_PROBE_OFFSET_FROM_EXTRUDER)) @@ -5280,7 +5305,7 @@ void home_all_axes() { gcode_G28(true); } #endif // Auto Bed Leveling is complete! Enable if possible. - planner.abl_enabled = dryrun ? abl_should_enable : true; + planner.leveling_active = dryrun ? abl_should_enable : true; } // !isnan(measured_z) // Restore state after probing @@ -5294,11 +5319,11 @@ void home_all_axes() { gcode_G28(true); } KEEPALIVE_STATE(IN_HANDLER); - if (planner.abl_enabled) + if (planner.leveling_active) SYNC_PLAN_POSITION_KINEMATIC(); } -#endif // HAS_ABL && !AUTO_BED_LEVELING_UBL +#endif // OLDSCHOOL_ABL #if HAS_BED_PROBE @@ -5309,13 +5334,13 @@ void home_all_axes() { gcode_G28(true); } * * X Probe X position (default current X) * Y Probe Y position (default current Y) - * S0 Leave the probe deployed + * E Engage the probe for each probe */ inline void gcode_G30() { const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER), ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER); - if (!position_is_reachable_by_probe_xy(xpos, ypos)) return; + if (!position_is_reachable_by_probe(xpos, ypos)) return; // Disable leveling so the planner won't mess with us #if HAS_LEVELING @@ -5324,7 +5349,7 @@ void home_all_axes() { gcode_G28(true); } setup_for_endstop_or_probe_move(); - const float measured_z = probe_pt(xpos, ypos, parser.boolval('S', true), 1); + const float measured_z = probe_pt(xpos, ypos, parser.boolval('E'), 1); if (!isnan(measured_z)) { SERIAL_PROTOCOLPAIR("Bed X: ", FIXFLOAT(xpos)); @@ -5353,447 +5378,670 @@ void home_all_axes() { gcode_G28(true); } #endif // HAS_BED_PROBE -#if PROBE_SELECTED +#if ENABLED(DELTA_AUTO_CALIBRATION) - #if ENABLED(DELTA_AUTO_CALIBRATION) - /** - * G33 - Delta '1-4-7-point' Auto-Calibration - * Calibrate height, endstops, delta radius, and tower angles. - * - * Parameters: - * - * Pn Number of probe points: - * - * P0 No probe. Normalize only. - * P1 Probe center and set height only. - * P2 Probe center and towers. Set height, endstops, and delta radius. - * P3 Probe all positions: center, towers and opposite towers. Set all. - * P4-P7 Probe all positions at different locations and average them. - * - * T0 Don't calibrate tower angle corrections - * - * Cn.nn Calibration precision; when omitted calibrates to maximum precision - * - * Fn Force to run at least n iterations and takes the best result - * - * Vn Verbose level: - * - * V0 Dry-run mode. Report settings and probe results. No calibration. - * V1 Report settings - * V2 Report settings and probe results - * - * E Engage the probe for each point - */ + constexpr uint8_t _7P_STEP = 1, // 7-point step - to change number of calibration points + _4P_STEP = _7P_STEP * 2, // 4-point step + NPP = _7P_STEP * 6; // number of calibration points on the radius + enum CalEnum { // the 7 main calibration points - add definitions if needed + CEN = 0, + __A = 1, + _AB = __A + _7P_STEP, + __B = _AB + _7P_STEP, + _BC = __B + _7P_STEP, + __C = _BC + _7P_STEP, + _CA = __C + _7P_STEP, + }; - void print_signed_float(const char * const prefix, const float &f) { - SERIAL_PROTOCOLPGM(" "); - serialprintPGM(prefix); - SERIAL_PROTOCOLCHAR(':'); - if (f >= 0) SERIAL_CHAR('+'); - SERIAL_PROTOCOL_F(f, 2); + #define LOOP_CAL_PT(VAR, S, N) for (uint8_t VAR=S; VAR<=NPP; VAR+=N) + #define F_LOOP_CAL_PT(VAR, S, N) for (float VAR=S; VARCEN+0.9999; VAR-=N) + #define LOOP_CAL_ALL(VAR) LOOP_CAL_PT(VAR, CEN, 1) + #define LOOP_CAL_RAD(VAR) LOOP_CAL_PT(VAR, __A, _7P_STEP) + #define LOOP_CAL_ACT(VAR, _4P, _OP) LOOP_CAL_PT(VAR, _OP ? _AB : __A, _4P ? _4P_STEP : _7P_STEP) + + static void print_signed_float(const char * const prefix, const float &f) { + SERIAL_PROTOCOLPGM(" "); + serialprintPGM(prefix); + SERIAL_PROTOCOLCHAR(':'); + if (f >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(f, 2); + } + + static void print_G33_settings(const bool end_stops, const bool tower_angles) { + SERIAL_PROTOCOLPAIR(".Height:", delta_height); + if (end_stops) { + print_signed_float(PSTR("Ex"), delta_endstop_adj[A_AXIS]); + print_signed_float(PSTR("Ey"), delta_endstop_adj[B_AXIS]); + print_signed_float(PSTR("Ez"), delta_endstop_adj[C_AXIS]); } - - void print_G33_settings(const bool end_stops, const bool tower_angles) { - SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]); - if (end_stops) { - print_signed_float(PSTR(" Ex"), endstop_adj[A_AXIS]); - print_signed_float(PSTR("Ey"), endstop_adj[B_AXIS]); - print_signed_float(PSTR("Ez"), endstop_adj[C_AXIS]); - SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); - } + if (end_stops && tower_angles) { + SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); SERIAL_EOL(); - if (tower_angles) { - SERIAL_PROTOCOLPGM(".Tower angle : "); - print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]); - print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]); - print_signed_float(PSTR("Tz"), delta_tower_angle_trim[C_AXIS]); - SERIAL_EOL(); - } + SERIAL_CHAR('.'); + SERIAL_PROTOCOL_SP(13); } - - void G33_cleanup( - #if HOTENDS > 1 - const uint8_t old_tool_index - #endif - ) { - #if ENABLED(DELTA_HOME_TO_SAFE_ZONE) - do_blocking_move_to_z(delta_clip_start_height); - #endif - STOW_PROBE(); - clean_up_after_endstop_or_probe_move(); - #if HOTENDS > 1 - tool_change(old_tool_index, 0, true); - #endif + if (tower_angles) { + print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]); + print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]); + print_signed_float(PSTR("Tz"), delta_tower_angle_trim[C_AXIS]); } + if ((!end_stops && tower_angles) || (end_stops && !tower_angles)) { // XOR + SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); + } + SERIAL_EOL(); + } - inline void gcode_G33() { + static void print_G33_results(const float z_at_pt[NPP + 1], const bool tower_points, const bool opposite_points) { + SERIAL_PROTOCOLPGM(". "); + print_signed_float(PSTR("c"), z_at_pt[CEN]); + if (tower_points) { + print_signed_float(PSTR(" x"), z_at_pt[__A]); + print_signed_float(PSTR(" y"), z_at_pt[__B]); + print_signed_float(PSTR(" z"), z_at_pt[__C]); + } + if (tower_points && opposite_points) { + SERIAL_EOL(); + SERIAL_CHAR('.'); + SERIAL_PROTOCOL_SP(13); + } + if (opposite_points) { + print_signed_float(PSTR("yz"), z_at_pt[_BC]); + print_signed_float(PSTR("zx"), z_at_pt[_CA]); + print_signed_float(PSTR("xy"), z_at_pt[_AB]); + } + SERIAL_EOL(); + } - const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); - if (!WITHIN(probe_points, 0, 7)) { - SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (0-7)."); - return; + /** + * After G33: + * - Move to the print ceiling (DELTA_HOME_TO_SAFE_ZONE only) + * - Stow the probe + * - Restore endstops state + * - Select the old tool, if needed + */ + static void G33_cleanup( + #if HOTENDS > 1 + const uint8_t old_tool_index + #endif + ) { + #if ENABLED(DELTA_HOME_TO_SAFE_ZONE) + do_blocking_move_to_z(delta_clip_start_height); + #endif + STOW_PROBE(); + clean_up_after_endstop_or_probe_move(); + #if HOTENDS > 1 + tool_change(old_tool_index, 0, true); + #endif + } + + inline float calibration_probe(const float nx, const float ny, const bool stow) { + #if HAS_BED_PROBE + return probe_pt(nx, ny, stow, 0, false); + #else + UNUSED(stow); + return lcd_probe_pt(nx, ny); + #endif + } + + static float probe_G33_points(float z_at_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each) { + const bool _0p_calibration = probe_points == 0, + _1p_calibration = probe_points == 1, + _4p_calibration = probe_points == 2, + _4p_opposite_points = _4p_calibration && !towers_set, + _7p_calibration = probe_points >= 3 || probe_points == 0, + _7p_no_intermediates = probe_points == 3, + _7p_1_intermediates = probe_points == 4, + _7p_2_intermediates = probe_points == 5, + _7p_4_intermediates = probe_points == 6, + _7p_6_intermediates = probe_points == 7, + _7p_8_intermediates = probe_points == 8, + _7p_11_intermediates = probe_points == 9, + _7p_14_intermediates = probe_points == 10, + _7p_intermed_points = probe_points >= 4, + _7p_6_centre = probe_points >= 5 && probe_points <= 7, + _7p_9_centre = probe_points >= 8; + + LOOP_CAL_ALL(axis) z_at_pt[axis] = 0.0; + + if (!_0p_calibration) { + + if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center + z_at_pt[CEN] += calibration_probe(0, 0, stow_after_each); + if (isnan(z_at_pt[CEN])) return NAN; } - const int8_t verbose_level = parser.byteval('V', 1); - if (!WITHIN(verbose_level, 0, 2)) { - SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-2)."); - return; + if (_7p_calibration) { // probe extra center points + const float start = _7p_9_centre ? _CA + _7P_STEP / 3.0 : _7p_6_centre ? _CA : __C, + steps = _7p_9_centre ? _4P_STEP / 3.0 : _7p_6_centre ? _7P_STEP : _4P_STEP; + I_LOOP_CAL_PT(axis, start, steps) { + const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), + r = delta_calibration_radius * 0.1; + z_at_pt[CEN] += calibration_probe(cos(a) * r, sin(a) * r, stow_after_each); + if (isnan(z_at_pt[CEN])) return NAN; + } + z_at_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points); } - const float calibration_precision = parser.floatval('C'); - if (calibration_precision < 0) { - SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>0)."); - return; - } - - const int8_t force_iterations = parser.intval('F', 0); - if (!WITHIN(force_iterations, 0, 30)) { - SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0-30)."); - return; - } - - const bool towers_set = parser.boolval('T', true), - stow_after_each = parser.boolval('E'), - _0p_calibration = probe_points == 0, - _1p_calibration = probe_points == 1, - _4p_calibration = probe_points == 2, - _4p_towers_points = _4p_calibration && towers_set, - _4p_opposite_points = _4p_calibration && !towers_set, - _7p_calibration = probe_points >= 3 || _0p_calibration, - _7p_half_circle = probe_points == 3, - _7p_double_circle = probe_points == 5, - _7p_triple_circle = probe_points == 6, - _7p_quadruple_circle = probe_points == 7, - _7p_multi_circle = _7p_double_circle || _7p_triple_circle || _7p_quadruple_circle, - _7p_intermed_points = _7p_calibration && !_7p_half_circle; - const static char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h"; - const float dx = (X_PROBE_OFFSET_FROM_EXTRUDER), - dy = (Y_PROBE_OFFSET_FROM_EXTRUDER); - int8_t iterations = 0; - float test_precision, - zero_std_dev = (verbose_level ? 999.0 : 0.0), // 0.0 in dry-run mode : forced end - zero_std_dev_old = zero_std_dev, - zero_std_dev_min = zero_std_dev, - e_old[ABC] = { - endstop_adj[A_AXIS], - endstop_adj[B_AXIS], - endstop_adj[C_AXIS] - }, - dr_old = delta_radius, - zh_old = home_offset[Z_AXIS], - ta_old[ABC] = { - delta_tower_angle_trim[A_AXIS], - delta_tower_angle_trim[B_AXIS], - delta_tower_angle_trim[C_AXIS] - }; - - if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable - const float circles = (_7p_quadruple_circle ? 1.5 : - _7p_triple_circle ? 1.0 : - _7p_double_circle ? 0.5 : 0), - r = (1 + circles * 0.1) * delta_calibration_radius; - for (uint8_t axis = 1; axis < 13; ++axis) { - const float a = RADIANS(180 + 30 * axis); - if (!position_is_reachable_xy(cos(a) * r, sin(a) * r)) { - SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible."); - return; + if (!_1p_calibration) { // probe the radius + const CalEnum start = _4p_opposite_points ? _AB : __A; + const float steps = _7p_14_intermediates ? _7P_STEP / 15.0 : // 15r * 6 + 10c = 100 + _7p_11_intermediates ? _7P_STEP / 12.0 : // 12r * 6 + 9c = 81 + _7p_8_intermediates ? _7P_STEP / 9.0 : // 9r * 6 + 10c = 64 + _7p_6_intermediates ? _7P_STEP / 7.0 : // 7r * 6 + 7c = 49 + _7p_4_intermediates ? _7P_STEP / 5.0 : // 5r * 6 + 6c = 36 + _7p_2_intermediates ? _7P_STEP / 3.0 : // 3r * 6 + 7c = 25 + _7p_1_intermediates ? _7P_STEP / 2.0 : // 2r * 6 + 4c = 16 + _7p_no_intermediates ? _7P_STEP : // 1r * 6 + 3c = 9 + _4P_STEP; // .5r * 6 + 1c = 4 + bool zig_zag = true; + F_LOOP_CAL_PT(axis, start, _7p_9_centre ? steps * 3 : steps) { + const int8_t offset = _7p_9_centre ? 1 : 0; + for (int8_t circle = -offset; circle <= offset; circle++) { + const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), + r = delta_calibration_radius * (1 + 0.1 * (zig_zag ? circle : - circle)), + interpol = fmod(axis, 1); + const float z_temp = calibration_probe(cos(a) * r, sin(a) * r, stow_after_each); + if (isnan(z_temp)) return NAN; + // split probe point to neighbouring calibration points + z_at_pt[uint8_t(round(axis - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90))); + z_at_pt[uint8_t(round(axis - interpol)) % NPP + 1] += z_temp * sq(sin(RADIANS(interpol * 90))); } + zig_zag = !zig_zag; } + if (_7p_intermed_points) + LOOP_CAL_RAD(axis) + z_at_pt[axis] /= _7P_STEP / steps; } - SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate"); - stepper.synchronize(); - #if HAS_LEVELING - reset_bed_level(); // After calibration bed-level data is no longer valid - #endif + float S1 = z_at_pt[CEN], + S2 = sq(z_at_pt[CEN]); + int16_t N = 1; + if (!_1p_calibration) { // std dev from zero plane + LOOP_CAL_ACT(axis, _4p_calibration, _4p_opposite_points) { + S1 += z_at_pt[axis]; + S2 += sq(z_at_pt[axis]); + N++; + } + return round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001; + } + } - #if HOTENDS > 1 - const uint8_t old_tool_index = active_extruder; - tool_change(0, 0, true); - #define G33_CLEANUP() G33_cleanup(old_tool_index) - #else - #define G33_CLEANUP() G33_cleanup() - #endif + return 0.00001; + } - setup_for_endstop_or_probe_move(); - endstops.enable(true); - if (!_0p_calibration) { - if (!home_delta()) - return; + #if HAS_BED_PROBE + + static bool G33_auto_tune() { + float z_at_pt[NPP + 1] = { 0.0 }, + z_at_pt_base[NPP + 1] = { 0.0 }, + z_temp, h_fac = 0.0, r_fac = 0.0, a_fac = 0.0, norm = 0.8; + + #define ZP(N,I) ((N) * z_at_pt[I]) + #define Z06(I) ZP(6, I) + #define Z03(I) ZP(3, I) + #define Z02(I) ZP(2, I) + #define Z01(I) ZP(1, I) + #define Z32(I) ZP(3/2, I) + + SERIAL_PROTOCOLPGM("AUTO TUNE baseline"); + SERIAL_EOL(); + if (isnan(probe_G33_points(z_at_pt_base, 3, true, false))) return false; + print_G33_results(z_at_pt_base, true, true); + + LOOP_XYZ(axis) { + delta_endstop_adj[axis] -= 1.0; + recalc_delta_settings(); + + endstops.enable(true); + if (!home_delta()) return false; endstops.not_homing(); + + SERIAL_PROTOCOLPGM("Tuning E"); + SERIAL_CHAR(tolower(axis_codes[axis])); + SERIAL_EOL(); + + if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; + LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; + print_G33_results(z_at_pt, true, true); + delta_endstop_adj[axis] += 1.0; + recalc_delta_settings(); + switch (axis) { + case A_AXIS : + h_fac += 4.0 / (Z03(CEN) +Z01(__A) +Z32(_CA) +Z32(_AB)); // Offset by X-tower end-stop + break; + case B_AXIS : + h_fac += 4.0 / (Z03(CEN) +Z01(__B) +Z32(_BC) +Z32(_AB)); // Offset by Y-tower end-stop + break; + case C_AXIS : + h_fac += 4.0 / (Z03(CEN) +Z01(__C) +Z32(_BC) +Z32(_CA) ); // Offset by Z-tower end-stop + break; + } + } + h_fac /= 3.0; + h_fac *= norm; // Normalize to 1.02 for Kossel mini + + for (int8_t zig_zag = -1; zig_zag < 2; zig_zag += 2) { + delta_radius += 1.0 * zig_zag; + recalc_delta_settings(); + + endstops.enable(true); + if (!home_delta()) return false; + endstops.not_homing(); + + SERIAL_PROTOCOLPGM("Tuning R"); + SERIAL_PROTOCOL(zig_zag == -1 ? "-" : "+"); + SERIAL_EOL(); + if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; + LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; + print_G33_results(z_at_pt, true, true); + delta_radius -= 1.0 * zig_zag; + recalc_delta_settings(); + r_fac -= zig_zag * 6.0 / (Z03(__A) +Z03(__B) +Z03(__C) +Z03(_BC) +Z03(_CA) +Z03(_AB)); // Offset by delta radius + } + r_fac /= 2.0; + r_fac *= 3 * norm; // Normalize to 2.25 for Kossel mini + + LOOP_XYZ(axis) { + delta_tower_angle_trim[axis] += 1.0; + delta_endstop_adj[(axis + 1) % 3] -= 1.0 / 4.5; + delta_endstop_adj[(axis + 2) % 3] += 1.0 / 4.5; + z_temp = MAX3(delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS]); + delta_height -= z_temp; + LOOP_XYZ(axis) delta_endstop_adj[axis] -= z_temp; + recalc_delta_settings(); + + endstops.enable(true); + if (!home_delta()) return false; + endstops.not_homing(); + + SERIAL_PROTOCOLPGM("Tuning T"); + SERIAL_CHAR(tolower(axis_codes[axis])); + SERIAL_EOL(); + + if (isnan(probe_G33_points(z_at_pt, 3, true, false))) return false; + LOOP_CAL_ALL(axis) z_at_pt[axis] -= z_at_pt_base[axis]; + print_G33_results(z_at_pt, true, true); + + delta_tower_angle_trim[axis] -= 1.0; + delta_endstop_adj[(axis+1) % 3] += 1.0/4.5; + delta_endstop_adj[(axis+2) % 3] -= 1.0/4.5; + z_temp = MAX3(delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS]); + delta_height -= z_temp; + LOOP_XYZ(axis) delta_endstop_adj[axis] -= z_temp; + recalc_delta_settings(); + switch (axis) { + case A_AXIS : + a_fac += 4.0 / ( Z06(__B) -Z06(__C) +Z06(_CA) -Z06(_AB)); // Offset by alpha tower angle + break; + case B_AXIS : + a_fac += 4.0 / (-Z06(__A) +Z06(__C) -Z06(_BC) +Z06(_AB)); // Offset by beta tower angle + break; + case C_AXIS : + a_fac += 4.0 / (Z06(__A) -Z06(__B) +Z06(_BC) -Z06(_CA) ); // Offset by gamma tower angle + break; + } + } + a_fac /= 3.0; + a_fac *= norm; // Normalize to 0.83 for Kossel mini + + endstops.enable(true); + if (!home_delta()) return false; + endstops.not_homing(); + print_signed_float(PSTR( "H_FACTOR: "), h_fac); + print_signed_float(PSTR(" R_FACTOR: "), r_fac); + print_signed_float(PSTR(" A_FACTOR: "), a_fac); + SERIAL_EOL(); + SERIAL_PROTOCOLPGM("Copy these values to Configuration.h"); + SERIAL_EOL(); + return true; + } + + #endif // HAS_BED_PROBE + + /** + * G33 - Delta '1-4-7-point' Auto-Calibration + * Calibrate height, endstops, delta radius, and tower angles. + * + * Parameters: + * + * Pn Number of probe points: + * P0 No probe. Normalize only. + * P1 Probe center and set height only. + * P2 Probe center and towers. Set height, endstops and delta radius. + * P3 Probe all positions: center, towers and opposite towers. Set all. + * P4-P10 Probe all positions + at different itermediate locations and average them. + * + * T Don't calibrate tower angle corrections + * + * Cn.nn Calibration precision; when omitted calibrates to maximum precision + * + * Fn Force to run at least n iterations and takes the best result + * + * A Auto tune calibartion factors (set in Configuration.h) + * + * Vn Verbose level: + * V0 Dry-run mode. Report settings and probe results. No calibration. + * V1 Report start and end settings only + * V2 Report settings at each iteration + * V3 Report settings and probe results + * + * E Engage the probe for each point + */ + inline void gcode_G33() { + + const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); + if (!WITHIN(probe_points, 0, 10)) { + SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (0-10)."); + return; + } + + const int8_t verbose_level = parser.byteval('V', 1); + if (!WITHIN(verbose_level, 0, 3)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-3)."); + return; + } + + const float calibration_precision = parser.floatval('C', 0.0); + if (calibration_precision < 0) { + SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>=0)."); + return; + } + + const int8_t force_iterations = parser.intval('F', 0); + if (!WITHIN(force_iterations, 0, 30)) { + SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0-30)."); + return; + } + + const bool towers_set = !parser.boolval('T'), + auto_tune = parser.boolval('A'), + stow_after_each = parser.boolval('E'), + _0p_calibration = probe_points == 0, + _1p_calibration = probe_points == 1, + _4p_calibration = probe_points == 2, + _7p_9_centre = probe_points >= 8, + _tower_results = (_4p_calibration && towers_set) + || probe_points >= 3 || probe_points == 0, + _opposite_results = (_4p_calibration && !towers_set) + || probe_points >= 3 || probe_points == 0, + _endstop_results = probe_points != 1, + _angle_results = (probe_points >= 3 || probe_points == 0) && towers_set; + const static char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h"; + int8_t iterations = 0; + float test_precision, + zero_std_dev = (verbose_level ? 999.0 : 0.0), // 0.0 in dry-run mode : forced end + zero_std_dev_min = zero_std_dev, + e_old[ABC] = { + delta_endstop_adj[A_AXIS], + delta_endstop_adj[B_AXIS], + delta_endstop_adj[C_AXIS] + }, + dr_old = delta_radius, + zh_old = delta_height, + ta_old[ABC] = { + delta_tower_angle_trim[A_AXIS], + delta_tower_angle_trim[B_AXIS], + delta_tower_angle_trim[C_AXIS] + }; + + SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate"); + + if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable + LOOP_CAL_RAD(axis) { + const float a = RADIANS(210 + (360 / NPP) * (axis - 1)), + r = delta_calibration_radius * (1 + (_7p_9_centre ? 0.1 : 0.0)); + if (!position_is_reachable(cos(a) * r, sin(a) * r)) { + SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible."); + return; + } + } + } + + stepper.synchronize(); + #if HAS_LEVELING + reset_bed_level(); // After calibration bed-level data is no longer valid + #endif + + #if HOTENDS > 1 + const uint8_t old_tool_index = active_extruder; + tool_change(0, 0, true); + #define G33_CLEANUP() G33_cleanup(old_tool_index) + #else + #define G33_CLEANUP() G33_cleanup() + #endif + + setup_for_endstop_or_probe_move(); + endstops.enable(true); + if (!_0p_calibration) { + if (!home_delta()) + return; + endstops.not_homing(); + } + + if (auto_tune) { + #if HAS_BED_PROBE + G33_auto_tune(); + #else + SERIAL_PROTOCOLLNPGM("A probe is needed for auto-tune"); + #endif + G33_CLEANUP(); + return; + } + + // Report settings + + const char *checkingac = PSTR("Checking... AC"); // TODO: Make translatable string + serialprintPGM(checkingac); + if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)"); + SERIAL_EOL(); + lcd_setstatusPGM(checkingac); + + print_G33_settings(_endstop_results, _angle_results); + + do { + + float z_at_pt[NPP + 1] = { 0.0 }; + + test_precision = zero_std_dev; + + iterations++; + + // Probe the points + + zero_std_dev = probe_G33_points(z_at_pt, probe_points, towers_set, stow_after_each); + if (isnan(zero_std_dev)) { + SERIAL_PROTOCOLPGM("Correct delta_radius with M665 R or end-stops with M666 X Y Z"); + SERIAL_EOL(); + return G33_CLEANUP(); } - // print settings - - const char *checkingac = PSTR("Checking... AC"); // TODO: Make translatable string - serialprintPGM(checkingac); - if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)"); - SERIAL_EOL(); - lcd_setstatusPGM(checkingac); - - print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); - - do { - - float z_at_pt[13] = { 0.0 }; - - test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev; - iterations++; - - // Probe the points - - if (!_0p_calibration){ - if (!_7p_half_circle && !_7p_triple_circle) { // probe the center - #if ENABLED(PROBE_MANUALLY) - z_at_pt[0] += lcd_probe_pt(0, 0); - #else - z_at_pt[0] += probe_pt(dx, dy, stow_after_each, 1, false); - if (isnan(z_at_pt[0])) return G33_CLEANUP(); - #endif - } - if (_7p_calibration) { // probe extra center points - for (int8_t axis = _7p_multi_circle ? 11 : 9; axis > 0; axis -= _7p_multi_circle ? 2 : 4) { - const float a = RADIANS(180 + 30 * axis), r = delta_calibration_radius * 0.1; - #if ENABLED(PROBE_MANUALLY) - z_at_pt[0] += lcd_probe_pt(cos(a) * r, sin(a) * r); - #else - z_at_pt[0] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1); - if (isnan(z_at_pt[0])) return G33_CLEANUP(); - #endif - } - z_at_pt[0] /= float(_7p_double_circle ? 7 : probe_points); - } - if (!_1p_calibration) { // probe the radius - bool zig_zag = true; - const uint8_t start = _4p_opposite_points ? 3 : 1, - step = _4p_calibration ? 4 : _7p_half_circle ? 2 : 1; - for (uint8_t axis = start; axis < 13; axis += step) { - const float zigadd = (zig_zag ? 0.5 : 0.0), - offset_circles = _7p_quadruple_circle ? zigadd + 1.0 : - _7p_triple_circle ? zigadd + 0.5 : - _7p_double_circle ? zigadd : 0; - for (float circles = -offset_circles ; circles <= offset_circles; circles++) { - const float a = RADIANS(180 + 30 * axis), - r = delta_calibration_radius * (1 + circles * (zig_zag ? 0.1 : -0.1)); - #if ENABLED(PROBE_MANUALLY) - z_at_pt[axis] += lcd_probe_pt(cos(a) * r, sin(a) * r); - #else - z_at_pt[axis] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1); - if (isnan(z_at_pt[axis])) return G33_CLEANUP(); - #endif - } - zig_zag = !zig_zag; - z_at_pt[axis] /= (2 * offset_circles + 1); - } - } - if (_7p_intermed_points) // average intermediates to tower and opposites - for (uint8_t axis = 1; axis < 13; axis += 2) - z_at_pt[axis] = (z_at_pt[axis] + (z_at_pt[axis + 1] + z_at_pt[(axis + 10) % 12 + 1]) / 2.0) / 2.0; + // Solve matrices + if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) { + if (zero_std_dev < zero_std_dev_min) { + COPY(e_old, delta_endstop_adj); + dr_old = delta_radius; + zh_old = delta_height; + COPY(ta_old, delta_tower_angle_trim); } - float S1 = z_at_pt[0], - S2 = sq(z_at_pt[0]); - int16_t N = 1; - if (!_1p_calibration) // std dev from zero plane - for (uint8_t axis = (_4p_opposite_points ? 3 : 1); axis < 13; axis += (_4p_calibration ? 4 : 2)) { - S1 += z_at_pt[axis]; - S2 += sq(z_at_pt[axis]); - N++; - } - zero_std_dev_old = zero_std_dev; - zero_std_dev = round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001; - // Solve matrices + float e_delta[ABC] = { 0.0 }, r_delta = 0.0, t_delta[ABC] = { 0.0 }; + const float r_diff = delta_radius - delta_calibration_radius, + h_factor = 1 / 6.0 * + #ifdef H_FACTOR + (H_FACTOR), // Set in Configuration.h + #else + (1.00 + r_diff * 0.001), // 1.02 for r_diff = 20mm + #endif + r_factor = 1 / 6.0 * + #ifdef R_FACTOR + -(R_FACTOR), // Set in Configuration.h + #else + -(1.75 + 0.005 * r_diff + 0.001 * sq(r_diff)), // 2.25 for r_diff = 20mm + #endif + a_factor = 1 / 6.0 * + #ifdef A_FACTOR + (A_FACTOR); // Set in Configuration.h + #else + (66.66 / delta_calibration_radius); // 0.83 for cal_rd = 80mm + #endif - if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) { - if (zero_std_dev < zero_std_dev_min) { - COPY(e_old, endstop_adj); - dr_old = delta_radius; - zh_old = home_offset[Z_AXIS]; - COPY(ta_old, delta_tower_angle_trim); - } + #define ZP(N,I) ((N) * z_at_pt[I]) + #define Z6(I) ZP(6, I) + #define Z4(I) ZP(4, I) + #define Z2(I) ZP(2, I) + #define Z1(I) ZP(1, I) - float e_delta[ABC] = { 0.0 }, r_delta = 0.0, t_delta[ABC] = { 0.0 }; + #if !HAS_BED_PROBE + test_precision = 0.00; // forced end + #endif - const float r_diff = delta_radius - delta_calibration_radius, - h_factor = (1.00 + r_diff * 0.001) / 6.0, // 1.02 for r_diff = 20mm - r_factor = (-(1.75 + 0.005 * r_diff + 0.001 * sq(r_diff))) / 6.0, // 2.25 for r_diff = 20mm - a_factor = (66.66 / delta_calibration_radius) / (iterations == 1 ? 16.0 : 2.0); // 0.83 for cal_rd = 80mm (Slow down on 1st iteration) - - #define ZP(N,I) ((N) * z_at_pt[I]) - #define Z6(I) ZP(6, I) - #define Z4(I) ZP(4, I) - #define Z2(I) ZP(2, I) - #define Z1(I) ZP(1, I) - - #if ENABLED(PROBE_MANUALLY) + switch (probe_points) { + case 0: test_precision = 0.00; // forced end - #endif + break; - switch (probe_points) { - case 0: - #if DISABLED(PROBE_MANUALLY) - test_precision = 0.00; // forced end - #endif - break; + case 1: + test_precision = 0.00; // forced end + LOOP_XYZ(axis) e_delta[axis] = Z1(CEN); + break; - case 1: - #if DISABLED(PROBE_MANUALLY) - test_precision = 0.00; // forced end - #endif - LOOP_XYZ(axis) e_delta[axis] = Z1(0); - break; + case 2: + if (towers_set) { + e_delta[A_AXIS] = (Z6(CEN) +Z4(__A) -Z2(__B) -Z2(__C)) * h_factor; + e_delta[B_AXIS] = (Z6(CEN) -Z2(__A) +Z4(__B) -Z2(__C)) * h_factor; + e_delta[C_AXIS] = (Z6(CEN) -Z2(__A) -Z2(__B) +Z4(__C)) * h_factor; + r_delta = (Z6(CEN) -Z2(__A) -Z2(__B) -Z2(__C)) * r_factor; + } + else { + e_delta[A_AXIS] = (Z6(CEN) -Z4(_BC) +Z2(_CA) +Z2(_AB)) * h_factor; + e_delta[B_AXIS] = (Z6(CEN) +Z2(_BC) -Z4(_CA) +Z2(_AB)) * h_factor; + e_delta[C_AXIS] = (Z6(CEN) +Z2(_BC) +Z2(_CA) -Z4(_AB)) * h_factor; + r_delta = (Z6(CEN) -Z2(_BC) -Z2(_CA) -Z2(_AB)) * r_factor; + } + break; - case 2: - if (towers_set) { - e_delta[A_AXIS] = (Z6(0) + Z4(1) - Z2(5) - Z2(9)) * h_factor; - e_delta[B_AXIS] = (Z6(0) - Z2(1) + Z4(5) - Z2(9)) * h_factor; - e_delta[C_AXIS] = (Z6(0) - Z2(1) - Z2(5) + Z4(9)) * h_factor; - r_delta = (Z6(0) - Z2(1) - Z2(5) - Z2(9)) * r_factor; - } - else { - e_delta[A_AXIS] = (Z6(0) - Z4(7) + Z2(11) + Z2(3)) * h_factor; - e_delta[B_AXIS] = (Z6(0) + Z2(7) - Z4(11) + Z2(3)) * h_factor; - e_delta[C_AXIS] = (Z6(0) + Z2(7) + Z2(11) - Z4(3)) * h_factor; - r_delta = (Z6(0) - Z2(7) - Z2(11) - Z2(3)) * r_factor; - } - break; + default: + e_delta[A_AXIS] = (Z6(CEN) +Z2(__A) -Z1(__B) -Z1(__C) -Z2(_BC) +Z1(_CA) +Z1(_AB)) * h_factor; + e_delta[B_AXIS] = (Z6(CEN) -Z1(__A) +Z2(__B) -Z1(__C) +Z1(_BC) -Z2(_CA) +Z1(_AB)) * h_factor; + e_delta[C_AXIS] = (Z6(CEN) -Z1(__A) -Z1(__B) +Z2(__C) +Z1(_BC) +Z1(_CA) -Z2(_AB)) * h_factor; + r_delta = (Z6(CEN) -Z1(__A) -Z1(__B) -Z1(__C) -Z1(_BC) -Z1(_CA) -Z1(_AB)) * r_factor; - default: - e_delta[A_AXIS] = (Z6(0) + Z2(1) - Z1(5) - Z1(9) - Z2(7) + Z1(11) + Z1(3)) * h_factor; - e_delta[B_AXIS] = (Z6(0) - Z1(1) + Z2(5) - Z1(9) + Z1(7) - Z2(11) + Z1(3)) * h_factor; - e_delta[C_AXIS] = (Z6(0) - Z1(1) - Z1(5) + Z2(9) + Z1(7) + Z1(11) - Z2(3)) * h_factor; - r_delta = (Z6(0) - Z1(1) - Z1(5) - Z1(9) - Z1(7) - Z1(11) - Z1(3)) * r_factor; - - if (towers_set) { - t_delta[A_AXIS] = ( - Z2(5) + Z2(9) - Z2(11) + Z2(3)) * a_factor; - t_delta[B_AXIS] = ( Z2(1) - Z2(9) + Z2(7) - Z2(3)) * a_factor; - t_delta[C_AXIS] = (-Z2(1) + Z2(5) - Z2(7) + Z2(11) ) * a_factor; - e_delta[A_AXIS] += (t_delta[B_AXIS] - t_delta[C_AXIS]) / 4.5; - e_delta[B_AXIS] += (t_delta[C_AXIS] - t_delta[A_AXIS]) / 4.5; - e_delta[C_AXIS] += (t_delta[A_AXIS] - t_delta[B_AXIS]) / 4.5; - } - break; - } - - LOOP_XYZ(axis) endstop_adj[axis] += e_delta[axis]; - delta_radius += r_delta; - LOOP_XYZ(axis) delta_tower_angle_trim[axis] += t_delta[axis]; - } - else if (zero_std_dev >= test_precision) { // step one back - COPY(endstop_adj, e_old); - delta_radius = dr_old; - home_offset[Z_AXIS] = zh_old; - COPY(delta_tower_angle_trim, ta_old); + if (towers_set) { + t_delta[A_AXIS] = ( -Z4(__B) +Z4(__C) -Z4(_CA) +Z4(_AB)) * a_factor; + t_delta[B_AXIS] = ( Z4(__A) -Z4(__C) +Z4(_BC) -Z4(_AB)) * a_factor; + t_delta[C_AXIS] = (-Z4(__A) +Z4(__B) -Z4(_BC) +Z4(_CA) ) * a_factor; + e_delta[A_AXIS] += (t_delta[B_AXIS] - t_delta[C_AXIS]) / 4.5; + e_delta[B_AXIS] += (t_delta[C_AXIS] - t_delta[A_AXIS]) / 4.5; + e_delta[C_AXIS] += (t_delta[A_AXIS] - t_delta[B_AXIS]) / 4.5; + } + break; } - if (verbose_level != 0) { // !dry run - // normalise angles to least squares + LOOP_XYZ(axis) delta_endstop_adj[axis] += e_delta[axis]; + delta_radius += r_delta; + LOOP_XYZ(axis) delta_tower_angle_trim[axis] += t_delta[axis]; + } + else if (zero_std_dev >= test_precision) { // step one back + COPY(delta_endstop_adj, e_old); + delta_radius = dr_old; + delta_height = zh_old; + COPY(delta_tower_angle_trim, ta_old); + } + + if (verbose_level != 0) { // !dry run + // normalise angles to least squares + if (_angle_results) { float a_sum = 0.0; LOOP_XYZ(axis) a_sum += delta_tower_angle_trim[axis]; LOOP_XYZ(axis) delta_tower_angle_trim[axis] -= a_sum / 3.0; - - // adjust delta_height and endstops by the max amount - const float z_temp = MAX3(endstop_adj[A_AXIS], endstop_adj[B_AXIS], endstop_adj[C_AXIS]); - home_offset[Z_AXIS] -= z_temp; - LOOP_XYZ(axis) endstop_adj[axis] -= z_temp; } - recalc_delta_settings(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); - NOMORE(zero_std_dev_min, zero_std_dev); - // print report + // adjust delta_height and endstops by the max amount + const float z_temp = MAX3(delta_endstop_adj[A_AXIS], delta_endstop_adj[B_AXIS], delta_endstop_adj[C_AXIS]); + delta_height -= z_temp; + LOOP_XYZ(axis) delta_endstop_adj[axis] -= z_temp; + } + recalc_delta_settings(); + NOMORE(zero_std_dev_min, zero_std_dev); - if (verbose_level != 1) { - SERIAL_PROTOCOLPGM(". "); - print_signed_float(PSTR("c"), z_at_pt[0]); - if (_4p_towers_points || _7p_calibration) { - print_signed_float(PSTR(" x"), z_at_pt[1]); - print_signed_float(PSTR(" y"), z_at_pt[5]); - print_signed_float(PSTR(" z"), z_at_pt[9]); - } - if (!_4p_opposite_points) SERIAL_EOL(); - if ((_4p_opposite_points) || _7p_calibration) { - if (_7p_calibration) { - SERIAL_CHAR('.'); - SERIAL_PROTOCOL_SP(13); + // print report + + if (verbose_level > 2) + print_G33_results(z_at_pt, _tower_results, _opposite_results); + + if (verbose_level != 0) { // !dry run + if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations + SERIAL_PROTOCOLPGM("Calibration OK"); + SERIAL_PROTOCOL_SP(32); + #if HAS_BED_PROBE + if (zero_std_dev >= test_precision && !_1p_calibration) + SERIAL_PROTOCOLPGM("rolling back."); + else + #endif + { + SERIAL_PROTOCOLPGM("std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev_min, 3); } - print_signed_float(PSTR(" yz"), z_at_pt[7]); - print_signed_float(PSTR("zx"), z_at_pt[11]); - print_signed_float(PSTR("xy"), z_at_pt[3]); - SERIAL_EOL(); - } + SERIAL_EOL(); + char mess[21]; + strcpy_P(mess, PSTR("Calibration sd:")); + if (zero_std_dev_min < 1) + sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev_min * 1000.0)); + else + sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev_min)); + lcd_setstatus(mess); + print_G33_settings(_endstop_results, _angle_results); + serialprintPGM(save_message); + SERIAL_EOL(); } - if (verbose_level != 0) { // !dry run - if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations - SERIAL_PROTOCOLPGM("Calibration OK"); - SERIAL_PROTOCOL_SP(36); - #if DISABLED(PROBE_MANUALLY) - if (zero_std_dev >= test_precision && !_1p_calibration) - SERIAL_PROTOCOLPGM("rolling back."); - else - #endif - { - SERIAL_PROTOCOLPGM("std dev:"); - SERIAL_PROTOCOL_F(zero_std_dev_min, 3); - } - SERIAL_EOL(); - char mess[21]; - sprintf_P(mess, PSTR("Calibration sd:")); - if (zero_std_dev_min < 1) - sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev_min * 1000.0)); - else - sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev_min)); - lcd_setstatus(mess); - print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); - serialprintPGM(save_message); - SERIAL_EOL(); - } - else { // !end iterations - char mess[15]; - if (iterations < 31) - sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations); - else - sprintf_P(mess, PSTR("No convergence")); - SERIAL_PROTOCOL(mess); - SERIAL_PROTOCOL_SP(36); - SERIAL_PROTOCOLPGM("std dev:"); - SERIAL_PROTOCOL_F(zero_std_dev, 3); - SERIAL_EOL(); - lcd_setstatus(mess); - print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); - } - } - else { // dry run - const char *enddryrun = PSTR("End DRY-RUN"); - serialprintPGM(enddryrun); - SERIAL_PROTOCOL_SP(39); + else { // !end iterations + char mess[15]; + if (iterations < 31) + sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations); + else + strcpy_P(mess, PSTR("No convergence")); + SERIAL_PROTOCOL(mess); + SERIAL_PROTOCOL_SP(32); SERIAL_PROTOCOLPGM("std dev:"); SERIAL_PROTOCOL_F(zero_std_dev, 3); SERIAL_EOL(); - - char mess[21]; - sprintf_P(mess, enddryrun); - sprintf_P(&mess[11], PSTR(" sd:")); - if (zero_std_dev < 1) - sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev * 1000.0)); - else - sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev)); lcd_setstatus(mess); + if (verbose_level > 1) + print_G33_settings(_endstop_results, _angle_results); } - - endstops.enable(true); - home_delta(); - endstops.not_homing(); - } - while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); + else { // dry run + const char *enddryrun = PSTR("End DRY-RUN"); + serialprintPGM(enddryrun); + SERIAL_PROTOCOL_SP(35); + SERIAL_PROTOCOLPGM("std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev, 3); + SERIAL_EOL(); + + char mess[21]; + strcpy_P(mess, enddryrun); + strcpy_P(&mess[11], PSTR(" sd:")); + if (zero_std_dev < 1) + sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev * 1000.0)); + else + sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev)); + lcd_setstatus(mess); + } + + endstops.enable(true); + if (!home_delta()) + return; + endstops.not_homing(); - G33_CLEANUP(); } + while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); - #endif // DELTA_AUTO_CALIBRATION + G33_CLEANUP(); + } -#endif // PROBE_SELECTED +#endif // DELTA_AUTO_CALIBRATION #if ENABLED(G38_PROBE_TARGET) @@ -5801,7 +6049,7 @@ void home_all_axes() { gcode_G28(true); } bool G38_pass_fail = false; - #if ENABLED(PROBE_DOUBLE_TOUCH) + #if MULTIPLE_PROBING > 1 // Get direction of move and retract float retract_mm[XYZ]; LOOP_XYZ(i) { @@ -5828,9 +6076,9 @@ void home_all_axes() { gcode_G28(true); } G38_pass_fail = true; - #if ENABLED(PROBE_DOUBLE_TOUCH) + #if MULTIPLE_PROBING > 1 // Move away by the retract distance - set_destination_to_current(); + set_destination_from_current(); LOOP_XYZ(i) destination[i] += retract_mm[i]; endstops.enable(false); prepare_move_to_destination(); @@ -5886,7 +6134,7 @@ void home_all_axes() { gcode_G28(true); } #endif // G38_PROBE_TARGET -#if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING) +#if HAS_MESH /** * G42: Move X & Y axes to mesh coordinates (I & J) @@ -5907,20 +6155,9 @@ void home_all_axes() { gcode_G28(true); } return; } - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - #define _GET_MESH_X(I) bilinear_start[X_AXIS] + I * bilinear_grid_spacing[X_AXIS] - #define _GET_MESH_Y(J) bilinear_start[Y_AXIS] + J * bilinear_grid_spacing[Y_AXIS] - #elif ENABLED(AUTO_BED_LEVELING_UBL) - #define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I) - #define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J) - #elif ENABLED(MESH_BED_LEVELING) - #define _GET_MESH_X(I) mbl.index_to_xpos[I] - #define _GET_MESH_Y(J) mbl.index_to_ypos[J] - #endif - - set_destination_to_current(); - if (hasI) destination[X_AXIS] = LOGICAL_X_POSITION(_GET_MESH_X(ix)); - if (hasJ) destination[Y_AXIS] = LOGICAL_Y_POSITION(_GET_MESH_Y(iy)); + set_destination_from_current(); + if (hasI) destination[X_AXIS] = _GET_MESH_X(ix); + if (hasJ) destination[Y_AXIS] = _GET_MESH_Y(iy); if (parser.boolval('P')) { if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; @@ -5938,45 +6175,74 @@ void home_all_axes() { gcode_G28(true); } } } -#endif // AUTO_BED_LEVELING_UBL +#endif // HAS_MESH /** * G92: Set current position to given X Y Z E */ inline void gcode_G92() { - bool didXYZ = false, - didE = parser.seenval('E'); - if (!didE) stepper.synchronize(); + stepper.synchronize(); - LOOP_XYZE(i) { + #if ENABLED(CNC_COORDINATE_SYSTEMS) + switch (parser.subcode) { + case 1: + // Zero the G92 values and restore current position + #if !IS_SCARA + LOOP_XYZ(i) { + const float v = position_shift[i]; + if (v) { + position_shift[i] = 0; + update_software_endstops((AxisEnum)i); + } + } + #endif // Not SCARA + return; + } + #endif + + #if ENABLED(CNC_COORDINATE_SYSTEMS) + #define IS_G92_0 (parser.subcode == 0) + #else + #define IS_G92_0 true + #endif + + bool didE = false; + #if IS_SCARA || !HAS_POSITION_SHIFT + bool didXYZ = false; + #else + constexpr bool didXYZ = false; + #endif + + if (IS_G92_0) LOOP_XYZE(i) { if (parser.seenval(axis_codes[i])) { - #if IS_SCARA - current_position[i] = parser.value_axis_units((AxisEnum)i); - if (i != E_AXIS) didXYZ = true; - #else - #if HAS_POSITION_SHIFT - const float p = current_position[i]; - #endif - const float v = parser.value_axis_units((AxisEnum)i); - - current_position[i] = v; - - if (i != E_AXIS) { - didXYZ = true; - #if HAS_POSITION_SHIFT - position_shift[i] += v - p; // Offset the coordinate space + const float l = parser.value_axis_units((AxisEnum)i), + v = i == E_AXIS ? l : LOGICAL_TO_NATIVE(l, i), + d = v - current_position[i]; + if (!NEAR_ZERO(d)) { + #if IS_SCARA || !HAS_POSITION_SHIFT + if (i == E_AXIS) didE = true; else didXYZ = true; + current_position[i] = v; // Without workspaces revert to Marlin 1.0 behavior + #elif HAS_POSITION_SHIFT + if (i == E_AXIS) { + didE = true; + current_position[E_AXIS] = v; // When using coordinate spaces, only E is set directly + } + else { + position_shift[i] += d; // Other axes simply offset the coordinate space update_software_endstops((AxisEnum)i); - - #if ENABLED(I2C_POSITION_ENCODERS) - I2CPEM.encoders[I2CPEM.idx_from_axis((AxisEnum)i)].set_axis_offset(position_shift[i]); - #endif - - #endif - } - #endif + } + #endif + } } } + + #if ENABLED(CNC_COORDINATE_SYSTEMS) + // Apply workspace offset to the active coordinate system + if (WITHIN(active_coordinate_system, 0, MAX_COORDINATE_SYSTEMS - 1)) + COPY(coordinate_system[active_coordinate_system], position_shift); + #endif + if (didXYZ) SYNC_PLAN_POSITION_KINEMATIC(); else if (didE) @@ -6039,7 +6305,7 @@ inline void gcode_G92() { #if ENABLED(ULTIPANEL) if (lcd_detected()) { while (wait_for_user) idle(); - IS_SD_PRINTING ? LCD_MESSAGEPGM(MSG_RESUMING) : LCD_MESSAGEPGM(WELCOME_MSG); + print_job_timer.isPaused() ? LCD_MESSAGEPGM(WELCOME_MSG) : LCD_MESSAGEPGM(MSG_RESUMING); } #else while (wait_for_user) idle(); @@ -6129,6 +6395,7 @@ inline void gcode_G92() { const float spindle_laser_power = parser.floatval('S'); if (spindle_laser_power == 0) { WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // turn spindle off (active low) + analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0); // only write low byte delay_for_power_down(); } else { @@ -6169,12 +6436,6 @@ inline void gcode_M17() { enable_all_steppers(); } -#if IS_KINEMATIC - #define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder) -#else - #define RUNPLAN(RATE_MM_S) line_to_destination(RATE_MM_S) -#endif - #if ENABLED(ADVANCED_PAUSE_FEATURE) static float resume_position[XYZE]; @@ -6218,6 +6479,19 @@ inline void gcode_M17() { } } + #if IS_KINEMATIC + #define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder) + #else + #define RUNPLAN(RATE_MM_S) buffer_line_to_destination(RATE_MM_S) + #endif + + void do_pause_e_move(const float &length, const float fr) { + current_position[E_AXIS] += length / planner.e_factor[active_extruder]; + set_destination_from_current(); + RUNPLAN(fr); + stepper.synchronize(); + } + static bool pause_print(const float &retract, const float &z_lift, const float &x_pos, const float &y_pos, const float &unload_length = 0 , const int8_t max_beep_count = 0, const bool show_lcd = false ) { @@ -6259,13 +6533,8 @@ inline void gcode_M17() { stepper.synchronize(); COPY(resume_position, current_position); - if (retract) { - // Initial retract before move to filament change position - set_destination_to_current(); - destination[E_AXIS] += retract; - RUNPLAN(PAUSE_PARK_RETRACT_FEEDRATE); - stepper.synchronize(); - } + // Initial retract before move to filament change position + if (retract) do_pause_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); // Lift Z axis if (z_lift > 0) @@ -6283,10 +6552,7 @@ inline void gcode_M17() { } // Unload filament - set_destination_to_current(); - destination[E_AXIS] += unload_length; - RUNPLAN(FILAMENT_CHANGE_UNLOAD_FEEDRATE); - stepper.synchronize(); + do_pause_e_move(unload_length, FILAMENT_CHANGE_UNLOAD_FEEDRATE); } if (show_lcd) { @@ -6387,7 +6653,7 @@ inline void gcode_M17() { filament_change_beep(max_beep_count, true); #endif - set_destination_to_current(); + set_destination_from_current(); if (load_length != 0) { #if ENABLED(ULTIPANEL) @@ -6412,9 +6678,7 @@ inline void gcode_M17() { #endif // Load filament - destination[E_AXIS] += load_length; - RUNPLAN(FILAMENT_CHANGE_LOAD_FEEDRATE); - stepper.synchronize(); + do_pause_e_move(load_length, FILAMENT_CHANGE_LOAD_FEEDRATE); } #if ENABLED(ULTIPANEL) && ADVANCED_PAUSE_EXTRUDE_LENGTH > 0 @@ -6427,9 +6691,7 @@ inline void gcode_M17() { lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_EXTRUDE); // Extrude filament to get into hotend - destination[E_AXIS] += extrude_length; - RUNPLAN(ADVANCED_PAUSE_EXTRUDE_FEEDRATE); - stepper.synchronize(); + do_pause_e_move(extrude_length, ADVANCED_PAUSE_EXTRUDE_FEEDRATE); } // Show "Extrude More" / "Resume" menu and wait for reply @@ -6588,19 +6850,23 @@ inline void gcode_M31() { /** * M32: Select file and start SD Print + * + * Examples: + * + * M32 !PATH/TO/FILE.GCO# ; Start FILE.GCO + * M32 P !PATH/TO/FILE.GCO# ; Start FILE.GCO as a procedure + * M32 S60 !PATH/TO/FILE.GCO# ; Start FILE.GCO at byte 60 + * */ inline void gcode_M32() { - if (card.sdprinting) - stepper.synchronize(); - - char* namestartpos = parser.string_arg; - const bool call_procedure = parser.boolval('P'); + if (card.sdprinting) stepper.synchronize(); if (card.cardOK) { - card.openFile(namestartpos, true, call_procedure); + const bool call_procedure = parser.boolval('P'); - if (parser.seenval('S')) - card.setIndex(parser.value_long()); + card.openFile(parser.string_arg, true, call_procedure); + + if (parser.seenval('S')) card.setIndex(parser.value_long()); card.startFileprint(); @@ -6708,7 +6974,7 @@ inline void gcode_M42() { const bool I_flag = parser.boolval('I'); const int repeat = parser.intval('R', 1), start = parser.intval('S'), - end = parser.intval('E', NUM_DIGITAL_PINS - 1), + end = parser.intval('L', NUM_DIGITAL_PINS - 1), wait = parser.intval('W', 500); for (uint8_t pin = start; pin <= end; pin++) { @@ -7007,10 +7273,7 @@ inline void gcode_M42() { * L = Number of legs of movement before probe * S = Schizoid (Or Star if you prefer) * - * This function assumes the bed has been homed. Specifically, that a G28 command - * as been issued prior to invoking the M48 Z probe repeatability measurement function. - * Any information generated by a prior G29 Bed leveling command will be lost and need to be - * regenerated. + * This function requires the machine to be homed before invocation. */ inline void gcode_M48() { @@ -7040,16 +7303,16 @@ inline void gcode_M42() { Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER); #if DISABLED(DELTA) - if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) { + if (!WITHIN(X_probe_location, MIN_PROBE_X, MAX_PROBE_X)) { out_of_range_error(PSTR("X")); return; } - if (!WITHIN(Y_probe_location, LOGICAL_Y_POSITION(MIN_PROBE_Y), LOGICAL_Y_POSITION(MAX_PROBE_Y))) { + if (!WITHIN(Y_probe_location, MIN_PROBE_Y, MAX_PROBE_Y)) { out_of_range_error(PSTR("Y")); return; } #else - if (!position_is_reachable_by_probe_xy(X_probe_location, Y_probe_location)) { + if (!position_is_reachable_by_probe(X_probe_location, Y_probe_location)) { SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius."); return; } @@ -7077,7 +7340,7 @@ inline void gcode_M42() { // Disable bed level correction in M48 because we want the raw data when we probe #if HAS_LEVELING - const bool was_enabled = leveling_is_active(); + const bool was_enabled = planner.leveling_active; set_bed_leveling_enabled(false); #endif @@ -7142,7 +7405,7 @@ inline void gcode_M42() { #else // If we have gone out too far, we can do a simple fix and scale the numbers // back in closer to the origin. - while (!position_is_reachable_by_probe_xy(X_current, Y_current)) { + while (!position_is_reachable_by_probe(X_current, Y_current)) { X_current *= 0.8; Y_current *= 0.8; if (verbose_level > 3) { @@ -7248,15 +7511,33 @@ inline void gcode_M42() { #endif // Z_MIN_PROBE_REPEATABILITY_TEST -#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) +#if ENABLED(G26_MESH_VALIDATION) inline void gcode_M49() { - ubl.g26_debug_flag ^= true; - SERIAL_PROTOCOLPGM("UBL Debug Flag turned "); - serialprintPGM(ubl.g26_debug_flag ? PSTR("on.") : PSTR("off.")); + g26_debug_flag ^= true; + SERIAL_PROTOCOLPGM("G26 Debug "); + serialprintPGM(g26_debug_flag ? PSTR("on.\n") : PSTR("off.\n")); } -#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION +#endif // G26_MESH_VALIDATION + +#if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY) + /** + * M73: Set percentage complete (for display on LCD) + * + * Example: + * M73 P25 ; Set progress to 25% + * + * Notes: + * This has no effect during an SD print job + */ + inline void gcode_M73() { + if (!IS_SD_PRINTING && parser.seen('P')) { + progress_bar_percent = parser.value_byte(); + NOMORE(progress_bar_percent, 100); + } + } +#endif // ULTRA_LCD && LCD_SET_PROGRESS_MANUALLY /** * M75: Start print timer @@ -7328,80 +7609,6 @@ inline void gcode_M104() { #endif } -#if HAS_TEMP_HOTEND || HAS_TEMP_BED - - void print_heater_state(const float &c, const float &t, - #if ENABLED(SHOW_TEMP_ADC_VALUES) - const float r, - #endif - const int8_t e=-2 - ) { - #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 - UNUSED(e); - #endif - - SERIAL_PROTOCOLCHAR(' '); - SERIAL_PROTOCOLCHAR( - #if HAS_TEMP_BED && HAS_TEMP_HOTEND - e == -1 ? 'B' : 'T' - #elif HAS_TEMP_HOTEND - 'T' - #else - 'B' - #endif - ); - #if HOTENDS > 1 - if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); - #endif - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(c); - SERIAL_PROTOCOLPAIR(" /" , t); - #if ENABLED(SHOW_TEMP_ADC_VALUES) - SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); - SERIAL_PROTOCOLCHAR(')'); - #endif - } - - void print_heaterstates() { - #if HAS_TEMP_HOTEND - print_heater_state(thermalManager.degHotend(target_extruder), thermalManager.degTargetHotend(target_extruder) - #if ENABLED(SHOW_TEMP_ADC_VALUES) - , thermalManager.rawHotendTemp(target_extruder) - #endif - ); - #endif - #if HAS_TEMP_BED - print_heater_state(thermalManager.degBed(), thermalManager.degTargetBed(), - #if ENABLED(SHOW_TEMP_ADC_VALUES) - thermalManager.rawBedTemp(), - #endif - -1 // BED - ); - #endif - #if HOTENDS > 1 - HOTEND_LOOP() print_heater_state(thermalManager.degHotend(e), thermalManager.degTargetHotend(e), - #if ENABLED(SHOW_TEMP_ADC_VALUES) - thermalManager.rawHotendTemp(e), - #endif - e - ); - #endif - SERIAL_PROTOCOLPGM(" @:"); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); - #if HAS_TEMP_BED - SERIAL_PROTOCOLPGM(" B@:"); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(-1)); - #endif - #if HOTENDS > 1 - HOTEND_LOOP() { - SERIAL_PROTOCOLPAIR(" @", e); - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(e)); - } - #endif - } -#endif - /** * M105: Read hot end and bed temperature */ @@ -7410,7 +7617,7 @@ inline void gcode_M105() { #if HAS_TEMP_HOTEND || HAS_TEMP_BED SERIAL_PROTOCOLPGM(MSG_OK); - print_heaterstates(); + thermalManager.print_heaterstates(); #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); @@ -7421,26 +7628,12 @@ inline void gcode_M105() { #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) - static uint8_t auto_report_temp_interval; - static millis_t next_temp_report_ms; - /** * M155: Set temperature auto-report interval. M155 S */ inline void gcode_M155() { - if (parser.seenval('S')) { - auto_report_temp_interval = parser.value_byte(); - NOMORE(auto_report_temp_interval, 60); - next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; - } - } - - inline void auto_report_temperatures() { - if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) { - next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; - print_heaterstates(); - SERIAL_EOL(); - } + if (parser.seenval('S')) + thermalManager.set_auto_report_interval(parser.value_byte()); } #endif // AUTO_REPORT_TEMPERATURES @@ -7452,12 +7645,38 @@ inline void gcode_M105() { * * S Speed between 0-255 * P Fan index, if more than one fan + * + * With EXTRA_FAN_SPEED enabled: + * + * T Restore/Use/Set Temporary Speed: + * 1 = Restore previous speed after T2 + * 2 = Use temporary speed set with T3-255 + * 3-255 = Set the speed for use with T2 */ inline void gcode_M106() { - uint16_t s = parser.ushortval('S', 255); - NOMORE(s, 255); - const uint8_t p = parser.byteval('P', 0); - if (p < FAN_COUNT) fanSpeeds[p] = s; + const uint8_t p = parser.byteval('P'); + if (p < FAN_COUNT) { + #if ENABLED(EXTRA_FAN_SPEED) + const int16_t t = parser.intval('T'); + if (t > 0) { + switch (t) { + case 1: + fanSpeeds[p] = old_fanSpeeds[p]; + break; + case 2: + old_fanSpeeds[p] = fanSpeeds[p]; + fanSpeeds[p] = new_fanSpeeds[p]; + break; + default: + new_fanSpeeds[p] = min(t, 255); + break; + } + return; + } + #endif // EXTRA_FAN_SPEED + const uint16_t s = parser.ushortval('S', 255); + fanSpeeds[p] = min(s, 255); + } } /** @@ -7583,7 +7802,7 @@ inline void gcode_M109() { now = millis(); if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting next_temp_ms = now + 1000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); #if TEMP_RESIDENCY_TIME > 0 SERIAL_PROTOCOLPGM(" W:"); if (residency_start_ms) @@ -7605,14 +7824,11 @@ inline void gcode_M109() { const uint8_t blue = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 255, 0); if (blue != old_blue) { old_blue = blue; - set_led_color(255, 0, blue - #if ENABLED(NEOPIXEL_LED) - , 0 - , pixels.getBrightness() + leds.set_color( + MakeLEDColor(255, 0, blue, 0, pixels.getBrightness()) #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) , true #endif - #endif ); } } @@ -7649,12 +7865,7 @@ inline void gcode_M109() { if (wait_for_heatup) { LCD_MESSAGEPGM(MSG_HEATING_COMPLETE); #if ENABLED(PRINTER_EVENT_LEDS) - #if ENABLED(RGB_LED) || ENABLED(BLINKM) || ENABLED(PCA9632) || ENABLED(RGBW_LED) - set_led_color(LED_WHITE); - #endif - #if ENABLED(NEOPIXEL_LED) - set_neopixel_color(pixels.Color(NEO_WHITE)); - #endif + leds.set_white(); #endif } @@ -7728,7 +7939,7 @@ inline void gcode_M109() { now = millis(); if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up. next_temp_ms = now + 1000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); #if TEMP_BED_RESIDENCY_TIME > 0 SERIAL_PROTOCOLPGM(" W:"); if (residency_start_ms) @@ -7750,12 +7961,10 @@ inline void gcode_M109() { const uint8_t red = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 0, 255); if (red != old_red) { old_red = red; - set_led_color(red, 0, 255 - #if ENABLED(NEOPIXEL_LED) - , 0, pixels.getBrightness() - #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) - , true - #endif + leds.set_color( + MakeLEDColor(red, 0, 255, 0, pixels.getBrightness()) + #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) + , true #endif ); } @@ -7982,6 +8191,11 @@ inline void gcode_M140() { #if ENABLED(ULTIPANEL) LCD_MESSAGEPGM(WELCOME_MSG); #endif + + #if ENABLED(HAVE_TMC2208) + delay(100); + tmc2208_init(); + #endif } #endif // HAS_POWER_SWITCH @@ -8051,7 +8265,7 @@ inline void gcode_M18_M84() { } #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD) // Only needed with an LCD - ubl_lcd_map_control = defer_return_to_status = false; + ubl.lcd_map_control = defer_return_to_status = false; #endif } } @@ -8109,11 +8323,11 @@ inline void gcode_M92() { */ void report_current_position() { SERIAL_PROTOCOLPGM("X:"); - SERIAL_PROTOCOL(current_position[X_AXIS]); + SERIAL_PROTOCOL(LOGICAL_X_POSITION(current_position[X_AXIS])); SERIAL_PROTOCOLPGM(" Y:"); - SERIAL_PROTOCOL(current_position[Y_AXIS]); + SERIAL_PROTOCOL(LOGICAL_Y_POSITION(current_position[Y_AXIS])); SERIAL_PROTOCOLPGM(" Z:"); - SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOL(LOGICAL_Z_POSITION(current_position[Z_AXIS])); SERIAL_PROTOCOLPGM(" E:"); SERIAL_PROTOCOL(current_position[E_AXIS]); @@ -8128,7 +8342,7 @@ void report_current_position() { #ifdef M114_DETAIL - void report_xyze(const float pos[XYZE], const uint8_t n = 4, const uint8_t precision = 3) { + void report_xyze(const float pos[], const uint8_t n = 4, const uint8_t precision = 3) { char str[12]; for (uint8_t i = 0; i < n; i++) { SERIAL_CHAR(' '); @@ -8139,28 +8353,35 @@ void report_current_position() { SERIAL_EOL(); } - inline void report_xyz(const float pos[XYZ]) { report_xyze(pos, 3); } + inline void report_xyz(const float pos[]) { report_xyze(pos, 3); } void report_current_position_detail() { stepper.synchronize(); SERIAL_PROTOCOLPGM("\nLogical:"); - report_xyze(current_position); + const float logical[XYZ] = { + LOGICAL_X_POSITION(current_position[X_AXIS]), + LOGICAL_Y_POSITION(current_position[Y_AXIS]), + LOGICAL_Z_POSITION(current_position[Z_AXIS]) + }; + report_xyze(logical); SERIAL_PROTOCOLPGM("Raw: "); - const float raw[XYZ] = { RAW_X_POSITION(current_position[X_AXIS]), RAW_Y_POSITION(current_position[Y_AXIS]), RAW_Z_POSITION(current_position[Z_AXIS]) }; - report_xyz(raw); + report_xyz(current_position); - SERIAL_PROTOCOLPGM("Leveled:"); float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; - planner.apply_leveling(leveled); - report_xyz(leveled); - SERIAL_PROTOCOLPGM("UnLevel:"); - float unleveled[XYZ] = { leveled[X_AXIS], leveled[Y_AXIS], leveled[Z_AXIS] }; - planner.unapply_leveling(unleveled); - report_xyz(unleveled); + #if PLANNER_LEVELING + SERIAL_PROTOCOLPGM("Leveled:"); + planner.apply_leveling(leveled); + report_xyz(leveled); + + SERIAL_PROTOCOLPGM("UnLevel:"); + float unleveled[XYZ] = { leveled[X_AXIS], leveled[Y_AXIS], leveled[Z_AXIS] }; + planner.unapply_leveling(unleveled); + report_xyz(unleveled); + #endif #if IS_KINEMATIC #if IS_SCARA @@ -8173,8 +8394,13 @@ void report_current_position() { #endif SERIAL_PROTOCOLPGM("Stepper:"); - const float step_count[XYZE] = { stepper.position(X_AXIS), stepper.position(Y_AXIS), stepper.position(Z_AXIS), stepper.position(E_AXIS) }; - report_xyze(step_count, 4, 0); + LOOP_XYZE(i) { + SERIAL_CHAR(' '); + SERIAL_CHAR(axis_codes[i]); + SERIAL_CHAR(':'); + SERIAL_PROTOCOL(stepper.position((AxisEnum)i)); + } + SERIAL_EOL(); #if IS_SCARA const float deg[XYZ] = { @@ -8220,78 +8446,107 @@ inline void gcode_M114() { /** * M115: Capabilities string */ + +#if ENABLED(EXTENDED_CAPABILITIES_REPORT) + static void cap_line(const char * const name, bool ena=false) { + SERIAL_PROTOCOLPGM("Cap:"); + serialprintPGM(name); + SERIAL_PROTOCOLLN(int(ena ? 1 : 0)); + } +#endif + inline void gcode_M115() { SERIAL_PROTOCOLLNPGM(MSG_M115_REPORT); #if ENABLED(EXTENDED_CAPABILITIES_REPORT) + // SERIAL_XON_XOFF + cap_line(PSTR("SERIAL_XON_XOFF") + #if ENABLED(SERIAL_XON_XOFF) + , true + #endif + ); + // EEPROM (M500, M501) - #if ENABLED(EEPROM_SETTINGS) - SERIAL_PROTOCOLLNPGM("Cap:EEPROM:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:EEPROM:0"); - #endif + cap_line(PSTR("EEPROM") + #if ENABLED(EEPROM_SETTINGS) + , true + #endif + ); + + // Volumetric Extrusion (M200) + cap_line(PSTR("VOLUMETRIC") + #if DISABLED(NO_VOLUMETRICS) + , true + #endif + ); // AUTOREPORT_TEMP (M155) - #if ENABLED(AUTO_REPORT_TEMPERATURES) - SERIAL_PROTOCOLLNPGM("Cap:AUTOREPORT_TEMP:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:AUTOREPORT_TEMP:0"); - #endif + cap_line(PSTR("AUTOREPORT_TEMP") + #if ENABLED(AUTO_REPORT_TEMPERATURES) + , true + #endif + ); // PROGRESS (M530 S L, M531 , M532 X L) - SERIAL_PROTOCOLLNPGM("Cap:PROGRESS:0"); + cap_line(PSTR("PROGRESS")); // Print Job timer M75, M76, M77 - SERIAL_PROTOCOLLNPGM("Cap:PRINT_JOB:1"); + cap_line(PSTR("PRINT_JOB"), true); // AUTOLEVEL (G29) - #if HAS_ABL - SERIAL_PROTOCOLLNPGM("Cap:AUTOLEVEL:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:AUTOLEVEL:0"); - #endif + cap_line(PSTR("AUTOLEVEL") + #if HAS_AUTOLEVEL + , true + #endif + ); // Z_PROBE (G30) - #if HAS_BED_PROBE - SERIAL_PROTOCOLLNPGM("Cap:Z_PROBE:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:Z_PROBE:0"); - #endif + cap_line(PSTR("Z_PROBE") + #if HAS_BED_PROBE + , true + #endif + ); // MESH_REPORT (M420 V) - #if HAS_LEVELING - SERIAL_PROTOCOLLNPGM("Cap:LEVELING_DATA:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:LEVELING_DATA:0"); - #endif + cap_line(PSTR("LEVELING_DATA") + #if HAS_LEVELING + , true + #endif + ); + + // BUILD_PERCENT (M73) + cap_line(PSTR("BUILD_PERCENT") + #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + , true + #endif + ); // SOFTWARE_POWER (M80, M81) - #if HAS_POWER_SWITCH - SERIAL_PROTOCOLLNPGM("Cap:SOFTWARE_POWER:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:SOFTWARE_POWER:0"); - #endif + cap_line(PSTR("SOFTWARE_POWER") + #if HAS_POWER_SWITCH + , true + #endif + ); // CASE LIGHTS (M355) - #if HAS_CASE_LIGHT - SERIAL_PROTOCOLLNPGM("Cap:TOGGLE_LIGHTS:1"); - if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) { - SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:1"); - } - else - SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:0"); - #else - SERIAL_PROTOCOLLNPGM("Cap:TOGGLE_LIGHTS:0"); - SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:0"); - #endif + cap_line(PSTR("TOGGLE_LIGHTS") + #if HAS_CASE_LIGHT + , true + #endif + ); + cap_line(PSTR("CASE_LIGHT_BRIGHTNESS") + #if HAS_CASE_LIGHT + , USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN) + #endif + ); // EMERGENCY_PARSER (M108, M112, M410) - #if ENABLED(EMERGENCY_PARSER) - SERIAL_PROTOCOLLNPGM("Cap:EMERGENCY_PARSER:1"); - #else - SERIAL_PROTOCOLLNPGM("Cap:EMERGENCY_PARSER:0"); - #endif + cap_line(PSTR("EMERGENCY_PARSER") + #if ENABLED(EMERGENCY_PARSER) + , true + #endif + ); #endif // EXTENDED_CAPABILITIES_REPORT } @@ -8304,8 +8559,8 @@ inline void gcode_M117() { lcd_setstatus(parser.string_arg); } /** * M118: Display a message in the host console. * - * A Append '// ' for an action command, as in OctoPrint - * E Have the host 'echo:' the text + * A1 Append '// ' for an action command, as in OctoPrint + * E1 Have the host 'echo:' the text */ inline void gcode_M118() { if (parser.boolval('E')) SERIAL_ECHO_START(); @@ -8418,45 +8673,40 @@ inline void gcode_M121() { endstops.enable_globally(false); } * M150 P ; Set LED full brightness */ inline void gcode_M150() { - set_led_color( + leds.set_color(MakeLEDColor( parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0, - parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0 - #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED) - , parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0 - #if ENABLED(NEOPIXEL_LED) - , parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : pixels.getBrightness() - #endif - #endif - ); + parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0, + parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0, + parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : pixels.getBrightness() + )); } #endif // HAS_COLOR_LEDS -/** - * M200: Set filament diameter and set E axis units to cubic units - * - * T - Optional extruder number. Current extruder if omitted. - * D - Diameter of the filament. Use "D0" to switch back to linear units on the E axis. - */ -inline void gcode_M200() { +#if DISABLED(NO_VOLUMETRICS) - if (get_target_extruder_from_command(200)) return; + /** + * M200: Set filament diameter and set E axis units to cubic units + * + * T - Optional extruder number. Current extruder if omitted. + * D - Diameter of the filament. Use "D0" to switch back to linear units on the E axis. + */ + inline void gcode_M200() { - if (parser.seen('D')) { - // setting any extruder filament size disables volumetric on the assumption that - // slicers either generate in extruder values as cubic mm or as as filament feeds - // for all extruders - volumetric_enabled = (parser.value_linear_units() != 0.0); - if (volumetric_enabled) { - filament_size[target_extruder] = parser.value_linear_units(); - // make sure all extruders have some sane value for the filament size - for (uint8_t i = 0; i < COUNT(filament_size); i++) - if (! filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; + if (get_target_extruder_from_command(200)) return; + + if (parser.seen('D')) { + // setting any extruder filament size disables volumetric on the assumption that + // slicers either generate in extruder values as cubic mm or as as filament feeds + // for all extruders + if ( (parser.volumetric_enabled = (parser.value_linear_units() != 0.0)) ) + planner.set_filament_size(target_extruder, parser.value_linear_units()); } + planner.calculate_volumetric_multipliers(); } - calculate_volumetric_multipliers(); -} + +#endif // !NO_VOLUMETRICS /** * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) @@ -8544,7 +8794,7 @@ inline void gcode_M204() { inline void gcode_M205() { if (parser.seen('S')) planner.min_feedrate_mm_s = parser.value_linear_units(); if (parser.seen('T')) planner.min_travel_feedrate_mm_s = parser.value_linear_units(); - if (parser.seen('B')) planner.min_segment_time = parser.value_millis(); + if (parser.seen('B')) planner.min_segment_time_us = parser.value_ulong(); if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units(); if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units(); if (parser.seen('Z')) planner.max_jerk[Z_AXIS] = parser.value_linear_units(); @@ -8566,11 +8816,10 @@ inline void gcode_M205() { set_home_offset((AxisEnum)i, parser.value_linear_units()); #if ENABLED(MORGAN_SCARA) - if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_linear_units()); // Theta - if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_linear_units()); // Psi + if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_float()); // Theta + if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi #endif - SYNC_PLAN_POSITION_KINEMATIC(); report_current_position(); } @@ -8590,10 +8839,7 @@ inline void gcode_M205() { * Z = Rotate A and B by this angle */ inline void gcode_M665() { - if (parser.seen('H')) { - home_offset[Z_AXIS] = parser.value_linear_units() - DELTA_HEIGHT; - update_software_endstops(Z_AXIS); - } + if (parser.seen('H')) delta_height = parser.value_linear_units(); if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units(); if (parser.seen('R')) delta_radius = parser.value_linear_units(); if (parser.seen('S')) delta_segments_per_second = parser.value_float(); @@ -8601,7 +8847,7 @@ inline void gcode_M205() { if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float(); if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float(); if (parser.seen('Z')) delta_tower_angle_trim[C_AXIS] = parser.value_float(); - recalc_delta_settings(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); + recalc_delta_settings(); } /** * M666: Set delta endstop adjustment @@ -8615,11 +8861,11 @@ inline void gcode_M205() { LOOP_XYZ(i) { if (parser.seen(axis_codes[i])) { if (parser.value_linear_units() * Z_HOME_DIR <= 0) - endstop_adj[i] = parser.value_linear_units(); + delta_endstop_adj[i] = parser.value_linear_units(); #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { - SERIAL_ECHOPAIR("endstop_adj[", axis_codes[i]); - SERIAL_ECHOLNPAIR("] = ", endstop_adj[i]); + SERIAL_ECHOPAIR("delta_endstop_adj[", axis_codes[i]); + SERIAL_ECHOLNPAIR("] = ", delta_endstop_adj[i]); } #endif } @@ -8669,14 +8915,28 @@ inline void gcode_M205() { } } -#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS) + + +#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) /** * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis. */ inline void gcode_M666() { - if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units(); - SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj); + SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): "); + #if ENABLED(X_DUAL_ENDSTOPS) + if (parser.seen('X')) x_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" X", x_endstop_adj); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (parser.seen('Y')) y_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Y", y_endstop_adj); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Z", z_endstop_adj); + #endif + SERIAL_EOL(); } #endif // !DELTA && Z_DUAL_ENDSTOPS @@ -8745,13 +9005,13 @@ inline void gcode_M211() { SERIAL_ECHOPGM(MSG_OFF); #endif SERIAL_ECHOPGM(MSG_SOFT_MIN); - SERIAL_ECHOPAIR( MSG_X, soft_endstop_min[X_AXIS]); - SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_min[Y_AXIS]); - SERIAL_ECHOPAIR(" " MSG_Z, soft_endstop_min[Z_AXIS]); + SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_min[X_AXIS])); + SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_min[Y_AXIS])); + SERIAL_ECHOPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_min[Z_AXIS])); SERIAL_ECHOPGM(MSG_SOFT_MAX); - SERIAL_ECHOPAIR( MSG_X, soft_endstop_max[X_AXIS]); - SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_max[Y_AXIS]); - SERIAL_ECHOLNPAIR(" " MSG_Z, soft_endstop_max[Z_AXIS]); + SERIAL_ECHOPAIR( MSG_X, LOGICAL_X_POSITION(soft_endstop_max[X_AXIS])); + SERIAL_ECHOPAIR(" " MSG_Y, LOGICAL_Y_POSITION(soft_endstop_max[Y_AXIS])); + SERIAL_ECHOLNPAIR(" " MSG_Z, LOGICAL_Z_POSITION(soft_endstop_max[Z_AXIS])); } #if HOTENDS > 1 @@ -8803,8 +9063,10 @@ inline void gcode_M220() { */ inline void gcode_M221() { if (get_target_extruder_from_command(221)) return; - if (parser.seenval('S')) - flow_percentage[target_extruder] = parser.value_int(); + if (parser.seenval('S')) { + planner.flow_percentage[target_extruder] = parser.value_int(); + planner.refresh_e_factor(target_extruder); + } } /** @@ -8919,6 +9181,42 @@ inline void gcode_M226() { #endif // HAS_SERVOS +#if ENABLED(BABYSTEPPING) + + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + FORCE_INLINE void mod_zprobe_zoffset(const float &offs) { + zprobe_zoffset += offs; + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(MSG_PROBE_Z_OFFSET ": ", zprobe_zoffset); + } + #endif + + /** + * M290: Babystepping + */ + inline void gcode_M290() { + #if ENABLED(BABYSTEP_XY) + for (uint8_t a = X_AXIS; a <= Z_AXIS; a++) + if (parser.seenval(axis_codes[a]) || (a == Z_AXIS && parser.seenval('S'))) { + const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2); + thermalManager.babystep_axis((AxisEnum)a, offs * planner.axis_steps_per_mm[a]); + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + if (a == Z_AXIS && (!parser.seen('P') || parser.value_bool())) mod_zprobe_zoffset(offs); + #endif + } + #else + if (parser.seenval('Z') || parser.seenval('S')) { + const float offs = constrain(parser.value_axis_units(Z_AXIS), -2, 2); + thermalManager.babystep_axis(Z_AXIS, offs * planner.axis_steps_per_mm[Z_AXIS]); + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + if (!parser.seen('P') || parser.value_bool()) mod_zprobe_zoffset(offs); + #endif + } + #endif + } + +#endif // BABYSTEPPING + #if HAS_BUZZER /** @@ -8995,8 +9293,6 @@ inline void gcode_M226() { if (parser.seen('I')) thermalManager.bedKi = scalePID_i(parser.value_float()); if (parser.seen('D')) thermalManager.bedKd = scalePID_d(parser.value_float()); - thermalManager.updatePID(); - SERIAL_ECHO_START(); SERIAL_ECHOPAIR(" p:", thermalManager.bedKp); SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bedKi)); @@ -9127,11 +9423,11 @@ inline void gcode_M303() { #if ENABLED(MORGAN_SCARA) - bool SCARA_move_to_cal(uint8_t delta_a, uint8_t delta_b) { + bool SCARA_move_to_cal(const uint8_t delta_a, const uint8_t delta_b) { if (IsRunning()) { forward_kinematics_SCARA(delta_a, delta_b); - destination[X_AXIS] = LOGICAL_X_POSITION(cartes[X_AXIS]); - destination[Y_AXIS] = LOGICAL_Y_POSITION(cartes[Y_AXIS]); + destination[X_AXIS] = cartes[X_AXIS]; + destination[Y_AXIS] = cartes[Y_AXIS]; destination[Z_AXIS] = current_position[Z_AXIS]; prepare_move_to_destination(); return true; @@ -9272,6 +9568,7 @@ inline void gcode_M400() { stepper.synchronize(); } inline void gcode_M404() { if (parser.seen('W')) { filament_width_nominal = parser.value_linear_units(); + planner.volumetric_area_nominal = CIRCLE_AREA(filament_width_nominal * 0.5); } else { SERIAL_PROTOCOLPGM("Filament dia (nominal mm):"); @@ -9291,7 +9588,7 @@ inline void gcode_M400() { stepper.synchronize(); } } if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup - const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte + const int8_t temp_ratio = thermalManager.widthFil_to_size_ratio(); for (uint8_t i = 0; i < COUNT(measurement_delay); ++i) measurement_delay[i] = temp_ratio; @@ -9300,11 +9597,6 @@ inline void gcode_M400() { stepper.synchronize(); } } filament_sensor = true; - - //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); - //SERIAL_PROTOCOL(filament_width_meas); - //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); - //SERIAL_PROTOCOL(flow_percentage[active_extruder]); } /** @@ -9312,7 +9604,7 @@ inline void gcode_M400() { stepper.synchronize(); } */ inline void gcode_M406() { filament_sensor = false; - calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value + planner.calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value } /** @@ -9346,13 +9638,15 @@ void quickstop_stepper() { */ inline void gcode_M420() { + const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; + #if ENABLED(AUTO_BED_LEVELING_UBL) // L to load a mesh from the EEPROM if (parser.seen('L')) { #if ENABLED(EEPROM_SETTINGS) - const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.state.storage_slot; + const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.storage_slot; const int16_t a = settings.calc_num_meshes(); if (!a) { @@ -9367,7 +9661,7 @@ void quickstop_stepper() { } settings.load_mesh(storage_slot); - ubl.state.storage_slot = storage_slot; + ubl.storage_slot = storage_slot; #else @@ -9380,8 +9674,8 @@ void quickstop_stepper() { // L to load a mesh from the EEPROM if (parser.seen('L') || parser.seen('V')) { ubl.display_map(0); // Currently only supports one map type - SERIAL_ECHOLNPAIR("UBL_MESH_VALID = ", UBL_MESH_VALID); - SERIAL_ECHOLNPAIR("ubl.state.storage_slot = ", ubl.state.storage_slot); + SERIAL_ECHOLNPAIR("ubl.mesh_is_valid = ", ubl.mesh_is_valid()); + SERIAL_ECHOLNPAIR("ubl.storage_slot = ", ubl.storage_slot); } #endif // AUTO_BED_LEVELING_UBL @@ -9405,15 +9699,17 @@ void quickstop_stepper() { #endif } - const bool to_enable = parser.boolval('S'); - if (parser.seen('S')) - set_bed_leveling_enabled(to_enable); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units()); + if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units(), false); #endif - const bool new_status = leveling_is_active(); + bool to_enable = false; + if (parser.seen('S')) { + to_enable = parser.value_bool(); + set_bed_leveling_enabled(to_enable); + } + + const bool new_status = planner.leveling_active; if (to_enable && !new_status) { SERIAL_ERROR_START(); @@ -9431,6 +9727,10 @@ void quickstop_stepper() { else SERIAL_ECHOLNPGM(MSG_OFF); #endif + + // Report change in position + if (memcmp(oldpos, current_position, sizeof(oldpos))) + report_current_position(); } #endif @@ -9447,9 +9747,9 @@ void quickstop_stepper() { */ inline void gcode_M421() { const bool hasX = parser.seen('X'), hasI = parser.seen('I'); - const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(RAW_X_POSITION(parser.value_linear_units())) : -1; + const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(parser.value_linear_units()) : -1; const bool hasY = parser.seen('Y'), hasJ = parser.seen('J'); - const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(RAW_Y_POSITION(parser.value_linear_units())) : -1; + const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(parser.value_linear_units()) : -1; const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) { @@ -9516,7 +9816,7 @@ void quickstop_stepper() { hasQ = !hasZ && parser.seen('Q'); if (hasC) { - const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false); + const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL); ix = location.x_index; iy = location.y_index; } @@ -9549,32 +9849,27 @@ void quickstop_stepper() { * Use M206 to set these values directly. */ inline void gcode_M428() { - bool err = false; + if (axis_unhomed_error()) return; + + float diff[XYZ]; LOOP_XYZ(i) { - if (axis_homed[i]) { - const float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos((AxisEnum)i) : 0, - diff = base - RAW_POSITION(current_position[i], i); - if (WITHIN(diff, -20, 20)) { - set_home_offset((AxisEnum)i, diff); - } - else { - SERIAL_ERROR_START(); - SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); - LCD_ALERTMESSAGEPGM("Err: Too far!"); - BUZZ(200, 40); - err = true; - break; - } + diff[i] = base_home_pos((AxisEnum)i) - current_position[i]; + if (!WITHIN(diff[i], -20, 20) && home_dir((AxisEnum)i) > 0) + diff[i] = -current_position[i]; + if (!WITHIN(diff[i], -20, 20)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); + LCD_ALERTMESSAGEPGM("Err: Too far!"); + BUZZ(200, 40); + return; } } - if (!err) { - SYNC_PLAN_POSITION_KINEMATIC(); - report_current_position(); - LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); - BUZZ(100, 659); - BUZZ(100, 698); - } + LOOP_XYZ(i) set_home_offset((AxisEnum)i, diff[i]); + report_current_position(); + LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); + BUZZ(100, 659); + BUZZ(100, 698); } #endif // HAS_M206_COMMAND @@ -9605,7 +9900,7 @@ inline void gcode_M502() { * M503: print settings currently in memory */ inline void gcode_M503() { - (void)settings.report(!parser.boolval('S', true)); + (void)settings.report(parser.seen('S') && !parser.value_bool()); } #endif @@ -9622,63 +9917,102 @@ inline void gcode_M502() { #if HAS_BED_PROBE - void refresh_zprobe_zoffset(const bool no_babystep/*=false*/) { - static float last_zoffset = NAN; - - if (!isnan(last_zoffset)) { - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(BABYSTEP_ZPROBE_OFFSET) || ENABLED(DELTA) - const float diff = zprobe_zoffset - last_zoffset; - #endif - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - // Correct bilinear grid for new probe offset - if (diff) { - for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) - for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) - z_values[x][y] -= diff; - } - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - bed_level_virt_interpolate(); - #endif - #endif - - #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - if (!no_babystep && leveling_is_active()) - thermalManager.babystep_axis(Z_AXIS, -LROUND(diff * planner.axis_steps_per_mm[Z_AXIS])); - #else - UNUSED(no_babystep); - #endif - - #if ENABLED(DELTA) // correct the delta_height - home_offset[Z_AXIS] -= diff; - #endif - } - - last_zoffset = zprobe_zoffset; - } - inline void gcode_M851() { SERIAL_ECHO_START(); - SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET " "); + SERIAL_ECHOPGM(MSG_PROBE_Z_OFFSET); if (parser.seen('Z')) { const float value = parser.value_linear_units(); - if (WITHIN(value, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { - zprobe_zoffset = value; - refresh_zprobe_zoffset(); - SERIAL_ECHO(zprobe_zoffset); + if (!WITHIN(value, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { + SERIAL_ECHOLNPGM(" " MSG_Z_MIN " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MIN) " " MSG_Z_MAX " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MAX)); + return; } - else - SERIAL_ECHOPGM(MSG_Z_MIN " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MIN) " " MSG_Z_MAX " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MAX)); + zprobe_zoffset = value; } - else - SERIAL_ECHOPAIR(": ", zprobe_zoffset); - - SERIAL_EOL(); + SERIAL_ECHOLNPAIR(": ", zprobe_zoffset); } #endif // HAS_BED_PROBE +#if ENABLED(SKEW_CORRECTION_GCODE) + + /** + * M852: Get or set the machine skew factors. Reports current values with no arguments. + * + * S[xy_factor] - Alias for 'I' + * I[xy_factor] - New XY skew factor + * J[xz_factor] - New XZ skew factor + * K[yz_factor] - New YZ skew factor + */ + inline void gcode_M852() { + uint8_t ijk = 0, badval = 0, setval = 0; + + if (parser.seen('I') || parser.seen('S')) { + ++ijk; + const float value = parser.value_linear_units(); + if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { + if (planner.xy_skew_factor != value) { + planner.xy_skew_factor = value; + ++setval; + } + } + else + ++badval; + } + + #if ENABLED(SKEW_CORRECTION_FOR_Z) + + if (parser.seen('J')) { + ++ijk; + const float value = parser.value_linear_units(); + if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { + if (planner.xz_skew_factor != value) { + planner.xz_skew_factor = value; + ++setval; + } + } + else + ++badval; + } + + if (parser.seen('K')) { + ++ijk; + const float value = parser.value_linear_units(); + if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { + if (planner.yz_skew_factor != value) { + planner.yz_skew_factor = value; + ++setval; + } + } + else + ++badval; + } + + #endif + + if (badval) + SERIAL_ECHOLNPGM(MSG_SKEW_MIN " " STRINGIFY(SKEW_FACTOR_MIN) " " MSG_SKEW_MAX " " STRINGIFY(SKEW_FACTOR_MAX)); + + // When skew is changed the current position changes + if (setval) { + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); + report_current_position(); + } + + if (!ijk) { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(MSG_SKEW_FACTOR " XY: ", planner.xy_skew_factor); + #if ENABLED(SKEW_CORRECTION_FOR_Z) + SERIAL_ECHOPAIR(" XZ: ", planner.xz_skew_factor); + SERIAL_ECHOLNPAIR(" YZ: ", planner.yz_skew_factor); + #else + SERIAL_EOL(); + #endif + } + } + +#endif // SKEW_CORRECTION_GCODE + #if ENABLED(ADVANCED_PAUSE_FEATURE) /** @@ -9884,122 +10218,479 @@ inline void gcode_M502() { } #endif // LIN_ADVANCE -#if ENABLED(HAVE_TMC2130) +#if HAS_TRINAMIC + static bool report_tmc_status = false; + const char extended_axis_codes[11][3] = { "X", "X2", "Y", "Y2", "Z", "Z2", "E0", "E1", "E2", "E3", "E4" }; + enum TMC_AxisEnum { + TMC_X, + TMC_X2, + TMC_Y, + TMC_Y2, + TMC_Z, + TMC_Z2, + TMC_E0, + TMC_E1, + TMC_E2, + TMC_E3, + TMC_E4 + }; + #if ENABLED(TMC_DEBUG) + enum TMC_debug_enum { + TMC_CODES, + TMC_ENABLED, + TMC_CURRENT, + TMC_RMS_CURRENT, + TMC_MAX_CURRENT, + TMC_IRUN, + TMC_IHOLD, + TMC_CS_ACTUAL, + TMC_PWM_SCALE, + TMC_VSENSE, + TMC_STEALTHCHOP, + TMC_MICROSTEPS, + TMC_TSTEP, + TMC_TPWMTHRS, + TMC_TPWMTHRS_MMS, + TMC_OTPW, + TMC_OTPW_TRIGGERED, + TMC_TOFF, + TMC_TBL, + TMC_HEND, + TMC_HSTRT, + TMC_SGT + }; + enum TMC_drv_status_enum { + TMC_DRV_CODES, + TMC_STST, + TMC_OLB, + TMC_OLA, + TMC_S2GB, + TMC_S2GA, + TMC_DRV_OTPW, + TMC_OT, + TMC_STALLGUARD, + TMC_DRV_CS_ACTUAL, + TMC_FSACTIVE, + TMC_SG_RESULT, + TMC_DRV_STATUS_HEX, + TMC_T157, + TMC_T150, + TMC_T143, + TMC_T120, + TMC_STEALTH, + TMC_S2VSB, + TMC_S2VSA + }; + static void drv_status_print_hex(const char name[], const uint32_t drv_status) { + SERIAL_ECHO(name); + SERIAL_ECHOPGM(" = 0x"); + for(int B=24; B>=8; B-=8){ + MYSERIAL.print((drv_status>>(B+4))&0xF, HEX); + MYSERIAL.print((drv_status>>B)&0xF, HEX); + MYSERIAL.print(':'); + } + MYSERIAL.print((drv_status>>4)&0xF, HEX); + MYSERIAL.print((drv_status)&0xF, HEX); + SERIAL_EOL(); + } - static void tmc2130_get_current(TMC2130Stepper &st, const char name) { - SERIAL_CHAR(name); + #if ENABLED(HAVE_TMC2130) + static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) { + switch(i) { + case TMC_PWM_SCALE: MYSERIAL.print(st.PWM_SCALE(), DEC); break; + case TMC_TSTEP: SERIAL_ECHO(st.TSTEP()); break; + case TMC_SGT: MYSERIAL.print(st.sgt(), DEC); break; + case TMC_STEALTHCHOP: serialprintPGM(st.stealthChop() ? PSTR("true") : PSTR("false")); break; + default: break; + } + } + static void tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) { + switch(i) { + case TMC_STALLGUARD: if (st.stallguard()) SERIAL_ECHOPGM("X"); break; + case TMC_SG_RESULT: MYSERIAL.print(st.sg_result(), DEC); break; + case TMC_FSACTIVE: if (st.fsactive()) SERIAL_ECHOPGM("X"); break; + default: break; + } + } + #endif + #if ENABLED(HAVE_TMC2208) + static void tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) { + switch(i) { + case TMC_TSTEP: + { + uint32_t data = 0; + st.TSTEP(&data); + MYSERIAL.print(data); + break; + } + case TMC_PWM_SCALE: MYSERIAL.print(st.pwm_scale_sum(), DEC); break; + case TMC_STEALTHCHOP: serialprintPGM(st.stealth() ? PSTR("true") : PSTR("false")); break; + case TMC_S2VSA: if (st.s2vsa()) SERIAL_ECHOPGM("X"); break; + case TMC_S2VSB: if (st.s2vsb()) SERIAL_ECHOPGM("X"); break; + default: break; + } + } + static void tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) { + switch(i) { + case TMC_T157: if (st.t157()) SERIAL_ECHOPGM("X"); break; + case TMC_T150: if (st.t150()) SERIAL_ECHOPGM("X"); break; + case TMC_T143: if (st.t143()) SERIAL_ECHOPGM("X"); break; + case TMC_T120: if (st.t120()) SERIAL_ECHOPGM("X"); break; + default: break; + } + } + #endif + template + static void tmc_status(TMC &st, TMC_AxisEnum axis, const TMC_debug_enum i, const float spmm) { + SERIAL_ECHO('\t'); + switch(i) { + case TMC_CODES: SERIAL_ECHO(extended_axis_codes[axis]); break; + case TMC_ENABLED: serialprintPGM(st.isEnabled() ? PSTR("true") : PSTR("false")); break; + case TMC_CURRENT: SERIAL_ECHO(st.getCurrent()); break; + case TMC_RMS_CURRENT: MYSERIAL.print(st.rms_current()); break; + case TMC_MAX_CURRENT: MYSERIAL.print((float)st.rms_current()*1.41, 0); break; + case TMC_IRUN: + MYSERIAL.print(st.irun(), DEC); + SERIAL_ECHOPGM("/31"); + break; + case TMC_IHOLD: + MYSERIAL.print(st.ihold(), DEC); + SERIAL_ECHOPGM("/31"); + break; + case TMC_CS_ACTUAL: + MYSERIAL.print(st.cs_actual(), DEC); + SERIAL_ECHOPGM("/31"); + break; + + case TMC_VSENSE: serialprintPGM(st.vsense() ? PSTR("1=.18") : PSTR("0=.325")); break; + + case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break; + case TMC_TPWMTHRS: + { + uint32_t tpwmthrs_val = st.TPWMTHRS(); + SERIAL_ECHO(tpwmthrs_val); + } + break; + case TMC_TPWMTHRS_MMS: + { + uint32_t tpwmthrs_val = st.TPWMTHRS(); + tpwmthrs_val ? SERIAL_ECHO(12650000UL * st.microsteps() / (256 * tpwmthrs_val * spmm)) : SERIAL_ECHO('-'); + } + break; + case TMC_OTPW: serialprintPGM(st.otpw() ? PSTR("true") : PSTR("false")); break; + case TMC_OTPW_TRIGGERED: serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); break; + case TMC_TOFF: MYSERIAL.print(st.toff(), DEC); break; + case TMC_TBL: MYSERIAL.print(st.blank_time(), DEC); break; + case TMC_HEND: MYSERIAL.print(st.hysterisis_end(), DEC); break; + case TMC_HSTRT: MYSERIAL.print(st.hysterisis_start(), DEC); break; + default: tmc_status(st, i); break; + } + } + template + static void tmc_parse_drv_status(TMC &st, TMC_AxisEnum axis, const TMC_drv_status_enum i) { + SERIAL_ECHOPGM("\t"); + switch(i) { + case TMC_DRV_CODES: SERIAL_ECHO(extended_axis_codes[axis]); break; + case TMC_STST: if (st.stst()) SERIAL_ECHOPGM("X"); break; + case TMC_OLB: if (st.olb()) SERIAL_ECHOPGM("X"); break; + case TMC_OLA: if (st.ola()) SERIAL_ECHOPGM("X"); break; + case TMC_S2GB: if (st.s2gb()) SERIAL_ECHOPGM("X"); break; + case TMC_S2GA: if (st.s2ga()) SERIAL_ECHOPGM("X"); break; + case TMC_DRV_OTPW: if (st.otpw()) SERIAL_ECHOPGM("X"); break; + case TMC_OT: if (st.ot()) SERIAL_ECHOPGM("X"); break; + case TMC_DRV_CS_ACTUAL: MYSERIAL.print(st.cs_actual(), DEC); break; + case TMC_DRV_STATUS_HEX:drv_status_print_hex(extended_axis_codes[axis], st.DRV_STATUS()); break; + default: tmc_parse_drv_status(st, i); break; + } + } + + static void tmc_debug_loop(const TMC_debug_enum i) { + #if X_IS_TRINAMIC + tmc_status(stepperX, TMC_X, i, planner.axis_steps_per_mm[X_AXIS]); + #endif + #if X2_IS_TRINAMIC + tmc_status(stepperX2, TMC_X2, i, planner.axis_steps_per_mm[X_AXIS]); + #endif + + #if Y_IS_TRINAMIC + tmc_status(stepperY, TMC_Y, i, planner.axis_steps_per_mm[Y_AXIS]); + #endif + #if Y2_IS_TRINAMIC + tmc_status(stepperY2, TMC_Y2, i, planner.axis_steps_per_mm[Y_AXIS]); + #endif + + #if Z_IS_TRINAMIC + tmc_status(stepperZ, TMC_Z, i, planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if Z2_IS_TRINAMIC + tmc_status(stepperZ2, TMC_Z2, i, planner.axis_steps_per_mm[Z_AXIS]); + #endif + + #if E0_IS_TRINAMIC + tmc_status(stepperE0, TMC_E0, i, planner.axis_steps_per_mm[E_AXIS]); + #endif + #if E1_IS_TRINAMIC + tmc_status(stepperE1, TMC_E1, i, planner.axis_steps_per_mm[E_AXIS+1]); + #endif + #if E2_IS_TRINAMIC + tmc_status(stepperE2, TMC_E2, i, planner.axis_steps_per_mm[E_AXIS+2]); + #endif + #if E3_IS_TRINAMIC + tmc_status(stepperE3, TMC_E3, i, planner.axis_steps_per_mm[E_AXIS+3]); + #endif + #if E4_IS_TRINAMIC + tmc_status(stepperE4, TMC_E4, i, planner.axis_steps_per_mm[E_AXIS+4]); + #endif + + SERIAL_EOL(); + } + + static void drv_status_loop(const TMC_drv_status_enum i) { + #if X_IS_TRINAMIC + tmc_parse_drv_status(stepperX, TMC_X, i); + #endif + #if X2_IS_TRINAMIC + tmc_parse_drv_status(stepperX2, TMC_X2, i); + #endif + + #if Y_IS_TRINAMIC + tmc_parse_drv_status(stepperY, TMC_Y, i); + #endif + #if Y2_IS_TRINAMIC + tmc_parse_drv_status(stepperY2, TMC_Y2, i); + #endif + + #if Z_IS_TRINAMIC + tmc_parse_drv_status(stepperZ, TMC_Z, i); + #endif + #if Z2_IS_TRINAMIC + tmc_parse_drv_status(stepperZ2, TMC_Z2, i); + #endif + + #if E0_IS_TRINAMIC + tmc_parse_drv_status(stepperE0, TMC_E0, i); + #endif + #if E1_IS_TRINAMIC + tmc_parse_drv_status(stepperE1, TMC_E1, i); + #endif + #if E2_IS_TRINAMIC + tmc_parse_drv_status(stepperE2, TMC_E2, i); + #endif + #if E3_IS_TRINAMIC + tmc_parse_drv_status(stepperE3, TMC_E3, i); + #endif + #if E4_IS_TRINAMIC + tmc_parse_drv_status(stepperE4, TMC_E4, i); + #endif + + SERIAL_EOL(); + } + + inline void gcode_M122() { + if (parser.seen('S')) { + if (parser.value_bool()) { + SERIAL_ECHOLNPGM("axis:pwm_scale |status_response|"); + report_tmc_status = true; + } else + report_tmc_status = false; + } else { + SERIAL_ECHOPGM("\t"); tmc_debug_loop(TMC_CODES); + SERIAL_ECHOPGM("Enabled\t"); tmc_debug_loop(TMC_ENABLED); + SERIAL_ECHOPGM("Set current"); tmc_debug_loop(TMC_CURRENT); + SERIAL_ECHOPGM("RMS current"); tmc_debug_loop(TMC_RMS_CURRENT); + SERIAL_ECHOPGM("MAX current"); tmc_debug_loop(TMC_MAX_CURRENT); + SERIAL_ECHOPGM("Run current"); tmc_debug_loop(TMC_IRUN); + SERIAL_ECHOPGM("Hold current"); tmc_debug_loop(TMC_IHOLD); + SERIAL_ECHOPGM("CS actual\t"); tmc_debug_loop(TMC_CS_ACTUAL); + SERIAL_ECHOPGM("PWM scale"); tmc_debug_loop(TMC_PWM_SCALE); + SERIAL_ECHOPGM("vsense\t"); tmc_debug_loop(TMC_VSENSE); + SERIAL_ECHOPGM("stealthChop"); tmc_debug_loop(TMC_STEALTHCHOP); + SERIAL_ECHOPGM("msteps\t"); tmc_debug_loop(TMC_MICROSTEPS); + SERIAL_ECHOPGM("tstep\t"); tmc_debug_loop(TMC_TSTEP); + SERIAL_ECHOPGM("pwm\nthreshold\t"); tmc_debug_loop(TMC_TPWMTHRS); + SERIAL_ECHOPGM("[mm/s]\t"); tmc_debug_loop(TMC_TPWMTHRS_MMS); + SERIAL_ECHOPGM("OT prewarn"); tmc_debug_loop(TMC_OTPW); + SERIAL_ECHOPGM("OT prewarn has\nbeen triggered"); tmc_debug_loop(TMC_OTPW_TRIGGERED); + SERIAL_ECHOPGM("off time\t"); tmc_debug_loop(TMC_TOFF); + SERIAL_ECHOPGM("blank time"); tmc_debug_loop(TMC_TBL); + SERIAL_ECHOPGM("hysterisis\n-end\t"); tmc_debug_loop(TMC_HEND); + SERIAL_ECHOPGM("-start\t"); tmc_debug_loop(TMC_HSTRT); + SERIAL_ECHOPGM("Stallguard thrs"); tmc_debug_loop(TMC_SGT); + + SERIAL_ECHOPGM("DRVSTATUS"); drv_status_loop(TMC_DRV_CODES); + #if ENABLED(HAVE_TMC2130) + SERIAL_ECHOPGM("stallguard\t"); drv_status_loop(TMC_STALLGUARD); + SERIAL_ECHOPGM("sg_result\t"); drv_status_loop(TMC_SG_RESULT); + SERIAL_ECHOPGM("fsactive\t"); drv_status_loop(TMC_FSACTIVE); + #endif + SERIAL_ECHOPGM("stst\t"); drv_status_loop(TMC_STST); + SERIAL_ECHOPGM("olb\t"); drv_status_loop(TMC_OLB); + SERIAL_ECHOPGM("ola\t"); drv_status_loop(TMC_OLA); + SERIAL_ECHOPGM("s2gb\t"); drv_status_loop(TMC_S2GB); + SERIAL_ECHOPGM("s2ga\t"); drv_status_loop(TMC_S2GA); + SERIAL_ECHOPGM("otpw\t"); drv_status_loop(TMC_DRV_OTPW); + SERIAL_ECHOPGM("ot\t"); drv_status_loop(TMC_OT); + #if ENABLED(HAVE_TMC2208) + SERIAL_ECHOPGM("157C\t"); drv_status_loop(TMC_T157); + SERIAL_ECHOPGM("150C\t"); drv_status_loop(TMC_T150); + SERIAL_ECHOPGM("143C\t"); drv_status_loop(TMC_T143); + SERIAL_ECHOPGM("120C\t"); drv_status_loop(TMC_T120); + SERIAL_ECHOPGM("s2vsa\t"); drv_status_loop(TMC_S2VSA); + SERIAL_ECHOPGM("s2vsb\t"); drv_status_loop(TMC_S2VSB); + #endif + SERIAL_ECHOLNPGM("Driver registers:");drv_status_loop(TMC_DRV_STATUS_HEX); + } + } + #endif + + template + static void tmc_get_current(TMC &st, const char name[]) { + SERIAL_ECHO(name); SERIAL_ECHOPGM(" axis driver current: "); SERIAL_ECHOLN(st.getCurrent()); } - static void tmc2130_set_current(TMC2130Stepper &st, const char name, const int mA) { + template + static void tmc_set_current(TMC &st, const char name[], const int mA) { st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER); - tmc2130_get_current(st, name); + tmc_get_current(st, name); } - static void tmc2130_report_otpw(TMC2130Stepper &st, const char name) { - SERIAL_CHAR(name); + template + static void tmc_report_otpw(TMC &st, const char name[]) { + SERIAL_ECHO(name); SERIAL_ECHOPGM(" axis temperature prewarn triggered: "); serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); SERIAL_EOL(); } - static void tmc2130_clear_otpw(TMC2130Stepper &st, const char name) { + template + static void tmc_clear_otpw(TMC &st, const char name[]) { st.clear_otpw(); - SERIAL_CHAR(name); + SERIAL_ECHO(name); SERIAL_ECHOLNPGM(" prewarn flag cleared"); } - static void tmc2130_get_pwmthrs(TMC2130Stepper &st, const char name, const uint16_t spmm) { - SERIAL_CHAR(name); + template + static void tmc_get_pwmthrs(TMC &st, const char name[], const uint16_t spmm) { + SERIAL_ECHO(name); SERIAL_ECHOPGM(" stealthChop max speed set to "); - SERIAL_ECHOLN(12650000UL * st.microsteps() / (256 * st.stealth_max_speed() * spmm)); + SERIAL_ECHOLN(12650000UL * st.microsteps() / (256 * st.TPWMTHRS() * spmm)); } - static void tmc2130_set_pwmthrs(TMC2130Stepper &st, const char name, const int32_t thrs, const uint32_t spmm) { - st.stealth_max_speed(12650000UL * st.microsteps() / (256 * thrs * spmm)); - tmc2130_get_pwmthrs(st, name, spmm); + template + static void tmc_set_pwmthrs(TMC &st, const char name[], const int32_t thrs, const uint32_t spmm) { + st.TPWMTHRS(12650000UL * st.microsteps() / (256 * thrs * spmm)); + tmc_get_pwmthrs(st, name, spmm); } - static void tmc2130_get_sgt(TMC2130Stepper &st, const char name) { - SERIAL_CHAR(name); + template + static void tmc_get_sgt(TMC &st, const char name[]) { + SERIAL_ECHO(name); SERIAL_ECHOPGM(" driver homing sensitivity set to "); - SERIAL_ECHOLN(st.sgt()); + MYSERIAL.println(st.sgt(), DEC); } - static void tmc2130_set_sgt(TMC2130Stepper &st, const char name, const int8_t sgt_val) { + template + static void tmc_set_sgt(TMC &st, const char name[], const int8_t sgt_val) { st.sgt(sgt_val); - tmc2130_get_sgt(st, name); + tmc_get_sgt(st, name); } /** * M906: Set motor current in milliamps using axis codes X, Y, Z, E * Report driver currents when no axis specified - * - * S1: Enable automatic current control - * S0: Disable */ inline void gcode_M906() { uint16_t values[XYZE]; LOOP_XYZE(i) values[i] = parser.intval(axis_codes[i]); - #if ENABLED(X_IS_TMC2130) - if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]); - else tmc2130_get_current(stepperX, 'X'); + #if X_IS_TRINAMIC + if (values[X_AXIS]) tmc_set_current(stepperX, extended_axis_codes[TMC_X], values[X_AXIS]); + else tmc_get_current(stepperX, extended_axis_codes[TMC_X]); #endif - #if ENABLED(Y_IS_TMC2130) - if (values[Y_AXIS]) tmc2130_set_current(stepperY, 'Y', values[Y_AXIS]); - else tmc2130_get_current(stepperY, 'Y'); + #if X2_IS_TRINAMIC + if (values[X_AXIS]) tmc_set_current(stepperX2, extended_axis_codes[TMC_X2], values[X_AXIS]); + else tmc_get_current(stepperX2, extended_axis_codes[TMC_X2]); #endif - #if ENABLED(Z_IS_TMC2130) - if (values[Z_AXIS]) tmc2130_set_current(stepperZ, 'Z', values[Z_AXIS]); - else tmc2130_get_current(stepperZ, 'Z'); + #if Y_IS_TRINAMIC + if (values[Y_AXIS]) tmc_set_current(stepperY, extended_axis_codes[TMC_Y], values[Y_AXIS]); + else tmc_get_current(stepperY, extended_axis_codes[TMC_Y]); #endif - #if ENABLED(E0_IS_TMC2130) - if (values[E_AXIS]) tmc2130_set_current(stepperE0, 'E', values[E_AXIS]); - else tmc2130_get_current(stepperE0, 'E'); + #if Y2_IS_TRINAMIC + if (values[Y_AXIS]) tmc_set_current(stepperY2, extended_axis_codes[TMC_Y2], values[Y_AXIS]); + else tmc_get_current(stepperY2, extended_axis_codes[TMC_Y2]); + #endif + #if Z_IS_TRINAMIC + if (values[Z_AXIS]) tmc_set_current(stepperZ, extended_axis_codes[TMC_Z], values[Z_AXIS]); + else tmc_get_current(stepperZ, extended_axis_codes[TMC_Z]); + #endif + #if Z2_IS_TRINAMIC + if (values[Z_AXIS]) tmc_set_current(stepperZ2, extended_axis_codes[TMC_Z2], values[Z_AXIS]); + else tmc_get_current(stepperZ2, extended_axis_codes[TMC_Z2]); + #endif + #if E0_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_current(stepperE0, extended_axis_codes[TMC_E0], values[E_AXIS]); + else tmc_get_current(stepperE0, extended_axis_codes[TMC_E0]); + #endif + #if E1_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_current(stepperE1, extended_axis_codes[TMC_E1], values[E_AXIS]); + else tmc_get_current(stepperE1, extended_axis_codes[TMC_E1]); + #endif + #if E2_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_current(stepperE2, extended_axis_codes[TMC_E2], values[E_AXIS]); + else tmc_get_current(stepperE2, extended_axis_codes[TMC_E2]); + #endif + #if E3_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_current(stepperE3, extended_axis_codes[TMC_E3], values[E_AXIS]); + else tmc_get_current(stepperE3, extended_axis_codes[TMC_E3]); + #endif + #if E4_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_current(stepperE4, extended_axis_codes[TMC_E4], values[E_AXIS]); + else tmc_get_current(stepperE4, extended_axis_codes[TMC_E4]); #endif - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - if (parser.seen('S')) auto_current_control = parser.value_bool(); - #endif } /** - * M911: Report TMC2130 stepper driver overtemperature pre-warn flag + * M911: Report TMC stepper driver overtemperature pre-warn flag * The flag is held by the library and persist until manually cleared by M912 */ inline void gcode_M911() { - const bool reportX = parser.seen('X'), reportY = parser.seen('Y'), reportZ = parser.seen('Z'), reportE = parser.seen('E'), - reportAll = (!reportX && !reportY && !reportZ && !reportE) || (reportX && reportY && reportZ && reportE); - #if ENABLED(X_IS_TMC2130) - if (reportX || reportAll) tmc2130_report_otpw(stepperX, 'X'); + #if ENABLED(X_IS_TMC2130) || (ENABLED(X_IS_TMC2208) && PIN_EXISTS(X_SERIAL_RX)) || ENABLED(IS_TRAMS) + tmc_report_otpw(stepperX, extended_axis_codes[TMC_X]); #endif - #if ENABLED(Y_IS_TMC2130) - if (reportY || reportAll) tmc2130_report_otpw(stepperY, 'Y'); + #if ENABLED(Y_IS_TMC2130) || (ENABLED(Y_IS_TMC2208) && PIN_EXISTS(Y_SERIAL_RX)) || ENABLED(IS_TRAMS) + tmc_report_otpw(stepperY, extended_axis_codes[TMC_Y]); #endif - #if ENABLED(Z_IS_TMC2130) - if (reportZ || reportAll) tmc2130_report_otpw(stepperZ, 'Z'); + #if ENABLED(Z_IS_TMC2130) || (ENABLED(Z_IS_TMC2208) && PIN_EXISTS(Z_SERIAL_RX)) || ENABLED(IS_TRAMS) + tmc_report_otpw(stepperZ, extended_axis_codes[TMC_Z]); #endif - #if ENABLED(E0_IS_TMC2130) - if (reportE || reportAll) tmc2130_report_otpw(stepperE0, 'E'); + #if ENABLED(E0_IS_TMC2130) || (ENABLED(E0_IS_TMC2208) && PIN_EXISTS(E0_SERIAL_RX)) || ENABLED(IS_TRAMS) + tmc_report_otpw(stepperE0, extended_axis_codes[TMC_E0]); #endif } /** - * M912: Clear TMC2130 stepper driver overtemperature pre-warn flag held by the library + * M912: Clear TMC stepper driver overtemperature pre-warn flag held by the library */ inline void gcode_M912() { - const bool clearX = parser.seen('X'), clearY = parser.seen('Y'), clearZ = parser.seen('Z'), clearE = parser.seen('E'), + const bool clearX = parser.seen(axis_codes[X_AXIS]), clearY = parser.seen(axis_codes[Y_AXIS]), clearZ = parser.seen(axis_codes[Z_AXIS]), clearE = parser.seen(axis_codes[E_AXIS]), clearAll = (!clearX && !clearY && !clearZ && !clearE) || (clearX && clearY && clearZ && clearE); - #if ENABLED(X_IS_TMC2130) - if (clearX || clearAll) tmc2130_clear_otpw(stepperX, 'X'); + #if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS) || (ENABLED(X_IS_TMC2208) && PIN_EXISTS(X_SERIAL_RX)) + if (clearX || clearAll) tmc_clear_otpw(stepperX, extended_axis_codes[TMC_X]); #endif - #if ENABLED(Y_IS_TMC2130) - if (clearY || clearAll) tmc2130_clear_otpw(stepperY, 'Y'); + #if ENABLED(X2_IS_TMC2130) || (ENABLED(X2_IS_TMC2208) && PIN_EXISTS(X_SERIAL_RX)) + if (clearX || clearAll) tmc_clear_otpw(stepperX, extended_axis_codes[TMC_X]); #endif - #if ENABLED(Z_IS_TMC2130) - if (clearZ || clearAll) tmc2130_clear_otpw(stepperZ, 'Z'); + + #if ENABLED(Y_IS_TMC2130) || (ENABLED(Y_IS_TMC2208) && PIN_EXISTS(Y_SERIAL_RX)) + if (clearY || clearAll) tmc_clear_otpw(stepperY, extended_axis_codes[TMC_Y]); #endif - #if ENABLED(E0_IS_TMC2130) - if (clearE || clearAll) tmc2130_clear_otpw(stepperE0, 'E'); + + #if ENABLED(Z_IS_TMC2130) || (ENABLED(Z_IS_TMC2208) && PIN_EXISTS(Z_SERIAL_RX)) + if (clearZ || clearAll) tmc_clear_otpw(stepperZ, extended_axis_codes[TMC_Z]); + #endif + + #if ENABLED(E0_IS_TMC2130) || (ENABLED(E0_IS_TMC2208) && PIN_EXISTS(E0_SERIAL_RX)) + if (clearE || clearAll) tmc_clear_otpw(stepperE0, extended_axis_codes[TMC_E0]); #endif } @@ -10012,21 +10703,52 @@ inline void gcode_M502() { LOOP_XYZE(i) values[i] = parser.intval(axis_codes[i]); - #if ENABLED(X_IS_TMC2130) - if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); - else tmc2130_get_pwmthrs(stepperX, 'X', planner.axis_steps_per_mm[X_AXIS]); + #if X_IS_TRINAMIC + if (values[X_AXIS]) tmc_set_pwmthrs(stepperX, extended_axis_codes[TMC_X], values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); + else tmc_get_pwmthrs(stepperX, extended_axis_codes[TMC_X], planner.axis_steps_per_mm[X_AXIS]); #endif - #if ENABLED(Y_IS_TMC2130) - if (values[Y_AXIS]) tmc2130_set_pwmthrs(stepperY, 'Y', values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]); - else tmc2130_get_pwmthrs(stepperY, 'Y', planner.axis_steps_per_mm[Y_AXIS]); + #if X2_IS_TRINAMIC + if (values[X_AXIS]) tmc_set_pwmthrs(stepperX2, extended_axis_codes[TMC_X2], values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); + else tmc_get_pwmthrs(stepperX, extended_axis_codes[TMC_X2], planner.axis_steps_per_mm[X_AXIS]); #endif - #if ENABLED(Z_IS_TMC2130) - if (values[Z_AXIS]) tmc2130_set_pwmthrs(stepperZ, 'Z', values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]); - else tmc2130_get_pwmthrs(stepperZ, 'Z', planner.axis_steps_per_mm[Z_AXIS]); + + #if Y_IS_TRINAMIC + if (values[Y_AXIS]) tmc_set_pwmthrs(stepperY, extended_axis_codes[TMC_Y], values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]); + else tmc_get_pwmthrs(stepperY, extended_axis_codes[TMC_Y], planner.axis_steps_per_mm[Y_AXIS]); #endif - #if ENABLED(E0_IS_TMC2130) - if (values[E_AXIS]) tmc2130_set_pwmthrs(stepperE0, 'E', values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); - else tmc2130_get_pwmthrs(stepperE0, 'E', planner.axis_steps_per_mm[E_AXIS]); + #if Y2_IS_TRINAMIC + if (values[Y_AXIS]) tmc_set_pwmthrs(stepperY2, extended_axis_codes[TMC_Y2], values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]); + else tmc_get_pwmthrs(stepperY, extended_axis_codes[TMC_Y2], planner.axis_steps_per_mm[Y_AXIS]); + #endif + + #if Z_IS_TRINAMIC + if (values[Z_AXIS]) tmc_set_pwmthrs(stepperZ, extended_axis_codes[TMC_Z], values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]); + else tmc_get_pwmthrs(stepperZ, extended_axis_codes[TMC_Z], planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if Z2_IS_TRINAMIC + if (values[Z_AXIS]) tmc_set_pwmthrs(stepperZ2, extended_axis_codes[TMC_Z2], values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]); + else tmc_get_pwmthrs(stepperZ, extended_axis_codes[TMC_Z2], planner.axis_steps_per_mm[Z_AXIS]); + #endif + + #if E0_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_pwmthrs(stepperE0, extended_axis_codes[TMC_E0], values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc_get_pwmthrs(stepperE0, extended_axis_codes[TMC_E0], planner.axis_steps_per_mm[E_AXIS]); + #endif + #if E1_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_pwmthrs(stepperE1, extended_axis_codes[TMC_E1], values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc_get_pwmthrs(stepperE1, extended_axis_codes[TMC_E1], planner.axis_steps_per_mm[E_AXIS]); + #endif + #if E2_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_pwmthrs(stepperE2, extended_axis_codes[TMC_E2], values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc_get_pwmthrs(stepperE2, extended_axis_codes[TMC_E2], planner.axis_steps_per_mm[E_AXIS]); + #endif + #if E3_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_pwmthrs(stepperE3, extended_axis_codes[TMC_E3], values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc_get_pwmthrs(stepperE3, extended_axis_codes[TMC_E3], planner.axis_steps_per_mm[E_AXIS]); + #endif + #if E4_IS_TRINAMIC + if (values[E_AXIS]) tmc_set_pwmthrs(stepperE4, extended_axis_codes[TMC_E4], values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc_get_pwmthrs(stepperE4, extended_axis_codes[TMC_E4], planner.axis_steps_per_mm[E_AXIS]); #endif } #endif // HYBRID_THRESHOLD @@ -10036,18 +10758,61 @@ inline void gcode_M502() { */ #if ENABLED(SENSORLESS_HOMING) inline void gcode_M914() { - #if ENABLED(X_IS_TMC2130) - if (parser.seen(axis_codes[X_AXIS])) tmc2130_set_sgt(stepperX, 'X', parser.value_int()); - else tmc2130_get_sgt(stepperX, 'X'); + #if ENABLED(X_IS_TMC2130) || ENABLED(IS_TRAMS) + if (parser.seen(axis_codes[X_AXIS])) tmc_set_sgt(stepperX, extended_axis_codes[TMC_X], parser.value_int()); + else tmc_get_sgt(stepperX, extended_axis_codes[TMC_X]); #endif - #if ENABLED(Y_IS_TMC2130) - if (parser.seen(axis_codes[Y_AXIS])) tmc2130_set_sgt(stepperY, 'Y', parser.value_int()); - else tmc2130_get_sgt(stepperY, 'Y'); + #if ENABLED(X2_IS_TMC2130) + if (parser.seen(axis_codes[X_AXIS])) tmc_set_sgt(stepperX2, extended_axis_codes[TMC_X2], parser.value_int()); + else tmc_get_sgt(stepperX2, extended_axis_codes[TMC_X2]); + #endif + #if ENABLED(Y_IS_TMC2130) || ENABLED(IS_TRAMS) + if (parser.seen(axis_codes[Y_AXIS])) tmc_set_sgt(stepperY, extended_axis_codes[TMC_Y], parser.value_int()); + else tmc_get_sgt(stepperY, extended_axis_codes[TMC_Y]); + #endif + #if ENABLED(Y2_IS_TMC2130) + if (parser.seen(axis_codes[Y_AXIS])) tmc_set_sgt(stepperY2, extended_axis_codes[TMC_Y2], parser.value_int()); + else tmc_get_sgt(stepperY2, extended_axis_codes[TMC_Y2]); #endif } #endif // SENSORLESS_HOMING -#endif // HAVE_TMC2130 + /** + * TMC Z axis calibration routine + */ + #if ENABLED(TMC_Z_CALIBRATION) && (Z_IS_TRINAMIC || Z2_IS_TRINAMIC) + inline void gcode_M915() { + uint16_t _rms = parser.seenval('S') ? parser.value_int() : CALIBRATION_CURRENT; + uint16_t _z = parser.seenval('Z') ? parser.value_int() : CALIBRATION_EXTRA_HEIGHT; + + if (!axis_known_position[Z_AXIS]) { + SERIAL_ECHOLNPGM("\nPlease home Z axis first"); + return; + } + + uint16_t Z_current_1 = stepperZ.getCurrent(); + uint16_t Z2_current_1 = stepperZ.getCurrent(); + + stepperZ.setCurrent(_rms, R_SENSE, HOLD_MULTIPLIER); + stepperZ2.setCurrent(_rms, R_SENSE, HOLD_MULTIPLIER); + SERIAL_ECHOPAIR("\nCalibration current: Z", _rms); + + soft_endstops_enabled = false; + + do_blocking_move_to_z(Z_MAX_POS+_z); + + stepperZ.setCurrent(Z_current_1, R_SENSE, HOLD_MULTIPLIER); + stepperZ2.setCurrent(Z2_current_1, R_SENSE, HOLD_MULTIPLIER); + + do_blocking_move_to_z(Z_MAX_POS); + soft_endstops_enabled = true; + + SERIAL_ECHOLNPGM("\nHoming Z because we lost steps"); + home_z_safely(); + } + #endif + +#endif // HAS_TRINAMIC /** * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S @@ -10159,12 +10924,17 @@ inline void gcode_M907() { void update_case_light() { pinMode(CASE_LIGHT_PIN, OUTPUT); // digitalWrite doesn't set the port mode if (case_light_on) { - if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) { + if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) analogWrite(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? 255 - case_light_brightness : case_light_brightness); - } - else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? LOW : HIGH); + else + WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? LOW : HIGH); + } + else { + if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) + analogWrite(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? 255 : 0); + else + WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? HIGH : LOW); } - else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? HIGH : LOW); } #endif // HAS_CASE_LIGHT @@ -10354,7 +11124,7 @@ inline void invalid_extruder_error(const uint8_t e) { #endif } - FORCE_INLINE void fanmux_init(void){ + FORCE_INLINE void fanmux_init(void) { SET_OUTPUT(FANMUX0_PIN); #if PIN_EXISTS(FANMUX1) SET_OUTPUT(FANMUX1_PIN); @@ -10401,7 +11171,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n } // Save current position to destination, for use later - set_destination_to_current(); + set_destination_from_current(); #if ENABLED(DUAL_X_CARRIAGE) @@ -10465,9 +11235,9 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n switch (dual_x_carriage_mode) { case DXC_FULL_CONTROL_MODE: // New current position is the position of the activated extruder - current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + current_position[X_AXIS] = inactive_extruder_x_pos; // Save the inactive extruder's position (from the old current_position) - inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + inactive_extruder_x_pos = destination[X_AXIS]; break; case DXC_AUTO_PARK_MODE: // record raised toolhead position for use by unpark @@ -10485,10 +11255,10 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n active_extruder_parked = (active_extruder == 0); if (active_extruder_parked) - current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + current_position[X_AXIS] = inactive_extruder_x_pos; else current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; - inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + inactive_extruder_x_pos = destination[X_AXIS]; extruder_duplication_enabled = false; #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { @@ -10512,22 +11282,22 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n #if ENABLED(PARKING_EXTRUDER) // Dual Parking extruder const float z_diff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder]; - float z_raise = 0; + float z_raise = PARKING_EXTRUDER_SECURITY_RAISE; if (!no_move) { const float parkingposx[] = PARKING_EXTRUDER_PARKING_X, - midpos = ((parkingposx[1] - parkingposx[0])/2) + parkingposx[0] + hotend_offset[X_AXIS][active_extruder], + midpos = (parkingposx[0] + parkingposx[1]) * 0.5 + hotend_offset[X_AXIS][active_extruder], grabpos = parkingposx[tmp_extruder] + hotend_offset[X_AXIS][active_extruder] + (tmp_extruder == 0 ? -(PARKING_EXTRUDER_GRAB_DISTANCE) : PARKING_EXTRUDER_GRAB_DISTANCE); /** * Steps: - * 1. raise Z-Axis to have enough clearance - * 2. move to park poition of old extruder - * 3. disengage magnetc field, wait for delay - * 4. move near new extruder - * 5. engage magnetic field for new extruder - * 6. move to parking incl. offset of new extruder - * 7. lower Z-Axis + * 1. Raise Z-Axis to give enough clearance + * 2. Move to park position of old extruder + * 3. Disengage magnetic field, wait for delay + * 4. Move near new extruder + * 5. Engage magnetic field for new extruder + * 6. Move to parking incl. offset of new extruder + * 7. Lower Z-Axis */ // STEP 1 @@ -10535,7 +11305,6 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n SERIAL_ECHOLNPGM("Starting Autopark"); if (DEBUGGING(LEVELING)) DEBUG_POS("current position:", current_position); #endif - z_raise = PARKING_EXTRUDER_SECURITY_RAISE; current_position[Z_AXIS] += z_raise; #if ENABLED(DEBUG_LEVELING_FEATURE) SERIAL_ECHOLNPGM("(1) Raise Z-Axis "); @@ -10691,7 +11460,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n #if ENABLED(MESH_BED_LEVELING) - if (leveling_is_active()) { + if (planner.leveling_active) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOPAIR("Z before MBL: ", current_position[Z_AXIS]); #endif @@ -10722,14 +11491,6 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n // The newly-selected extruder XY is actually at... current_position[X_AXIS] += xydiff[X_AXIS]; current_position[Y_AXIS] += xydiff[Y_AXIS]; - #if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE) || ENABLED(PARKING_EXTRUDER) - for (uint8_t i = X_AXIS; i <= Y_AXIS; i++) { - #if HAS_POSITION_SHIFT - position_shift[i] += xydiff[i]; - #endif - update_software_endstops((AxisEnum)i); - } - #endif // Set the new active extruder active_extruder = tmp_extruder; @@ -10744,22 +11505,22 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n SYNC_PLAN_POSITION_KINEMATIC(); // Move to the "old position" (move the extruder into place) + #if ENABLED(SWITCHING_NOZZLE) + destination[Z_AXIS] += z_diff; // Include the Z restore with the "move back" + #endif if (!no_move && IsRunning()) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); #endif - prepare_move_to_destination(); + // Move back to the original (or tweaked) position + do_blocking_move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS]); } - #if ENABLED(SWITCHING_NOZZLE) - // Move back down, if needed. (Including when the new tool is higher.) - if (z_raise != z_diff) { - destination[Z_AXIS] += z_diff; - feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; - prepare_move_to_destination(); + else { + // Move back down. (Including when the new tool is higher.) + do_blocking_move_to_z(destination[Z_AXIS], planner.max_feedrate_mm_s[Z_AXIS]); } #endif - } // (tmp_extruder != active_extruder) stepper.synchronize(); @@ -10809,7 +11570,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n * F[units/min] Set the movement feedrate * S1 Don't move the tool in XY after change */ -inline void gcode_T(uint8_t tmp_extruder) { +inline void gcode_T(const uint8_t tmp_extruder) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { @@ -10843,26 +11604,11 @@ inline void gcode_T(uint8_t tmp_extruder) { } /** - * Process a single command and dispatch it to its handler - * This is called from the main loop() + * Process the parsed command and dispatch it to its handler */ -void process_next_command() { - char * const current_command = command_queue[cmd_queue_index_r]; - - if (DEBUGGING(ECHO)) { - SERIAL_ECHO_START(); - SERIAL_ECHOLN(current_command); - #if ENABLED(M100_FREE_MEMORY_WATCHER) - SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); - M100_dump_routine(" Command Queue:", (const char*)command_queue, (const char*)(command_queue + sizeof(command_queue))); - #endif - } - +void process_parsed_command() { KEEPALIVE_STATE(IN_HANDLER); - // Parse the next command in the queue - parser.parse(current_command); - // Handle a known G, M, or T switch (parser.command_letter) { case 'G': switch (parser.codenum) { @@ -10933,11 +11679,11 @@ void process_next_command() { break; #endif // INCH_MODE_SUPPORT - #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + #if ENABLED(G26_MESH_VALIDATION) case 26: // G26: Mesh Validation Pattern generation gcode_G26(); break; - #endif // AUTO_BED_LEVELING_UBL + #endif // G26_MESH_VALIDATION #if ENABLED(NOZZLE_PARK_FEATURE) case 27: // G27: Nozzle Park @@ -10976,17 +11722,13 @@ void process_next_command() { #endif // HAS_BED_PROBE - #if PROBE_SELECTED + #if ENABLED(DELTA_AUTO_CALIBRATION) - #if ENABLED(DELTA_AUTO_CALIBRATION) + case 33: // G33: Delta Auto-Calibration + gcode_G33(); + break; - case 33: // G33: Delta Auto-Calibration - gcode_G33(); - break; - - #endif // DELTA_AUTO_CALIBRATION - - #endif // PROBE_SELECTED + #endif // DELTA_AUTO_CALIBRATION #if ENABLED(G38_PROBE_TARGET) case 38: // G38.2 & G38.3 @@ -11006,7 +11748,7 @@ void process_next_command() { gcode_G92(); break; - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING) + #if HAS_MESH case 42: gcode_G42(); break; @@ -11101,11 +11843,16 @@ void process_next_command() { break; #endif // Z_MIN_PROBE_REPEATABILITY_TEST - #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + #if ENABLED(G26_MESH_VALIDATION) case 49: // M49: Turn on or off G26 debug flag for verbose output gcode_M49(); break; - #endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION + #endif // G26_MESH_VALIDATION + + #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY) + case 73: // M73: Set print progress percentage + gcode_M73(); break; + #endif case 75: // M75: Start print timer gcode_M75(); break; @@ -11308,9 +12055,12 @@ void process_next_command() { #endif #endif - case 200: // M200: Set filament diameter, E to cubic units - gcode_M200(); - break; + #if DISABLED(NO_VOLUMETRICS) + case 200: // M200: Set filament diameter, E to cubic units + gcode_M200(); + break; + #endif + case 201: // M201: Set max acceleration for print moves (units/s^2) gcode_M201(); break; @@ -11341,7 +12091,7 @@ void process_next_command() { break; #endif - #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS) + #if ENABLED(DELTA) || ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) case 666: // M666: Set delta or dual endstop adjustment gcode_M666(); break; @@ -11367,7 +12117,7 @@ void process_next_command() { case 218: // M218: Set a tool offset gcode_M218(); break; - #endif + #endif // HOTENDS > 1 case 220: // M220: Set Feedrate Percentage: S ("FR" on your LCD) gcode_M220(); @@ -11387,6 +12137,12 @@ void process_next_command() { break; #endif // HAS_SERVOS + #if ENABLED(BABYSTEPPING) + case 290: // M290: Babystepping + gcode_M290(); + break; + #endif // BABYSTEPPING + #if HAS_BUZZER case 300: // M300: Play beep tone gcode_M300(); @@ -11491,7 +12247,7 @@ void process_next_command() { break; #endif - #if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + #if HAS_MESH case 421: // M421: Set a Mesh Bed Leveling Z coordinate gcode_M421(); break; @@ -11531,6 +12287,12 @@ void process_next_command() { break; #endif // HAS_BED_PROBE + #if ENABLED(SKEW_CORRECTION_GCODE) + case 852: // M852: Set Skew factors + gcode_M852(); + break; + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) case 600: // M600: Pause for filament change gcode_M600(); @@ -11555,12 +12317,6 @@ void process_next_command() { break; #endif - #if ENABLED(HAVE_TMC2130) - case 906: // M906: Set motor current in milliamps using axis codes X, Y, Z, E - gcode_M906(); - break; - #endif - case 907: // M907: Set digital trimpot motor current using axis codes. gcode_M907(); break; @@ -11585,15 +12341,25 @@ void process_next_command() { #endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT - #if ENABLED(HAVE_TMC2130) - case 911: // M911: Report TMC2130 prewarn triggered flags + #if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) + case 906: // M906: Set motor current in milliamps using axis codes X, Y, Z, E + gcode_M906(); + break; + + case 911: // M911: Report TMC prewarn triggered flags gcode_M911(); break; - case 912: // M911: Clear TMC2130 prewarn triggered flags + case 912: // M911: Clear TMC prewarn triggered flags gcode_M912(); break; + #if ENABLED(TMC_DEBUG) + case 122: // Debug TMC steppers + gcode_M122(); + break; + #endif + #if ENABLED(HYBRID_THRESHOLD) case 913: // M913: Set HYBRID_THRESHOLD speed. gcode_M913(); @@ -11605,6 +12371,12 @@ void process_next_command() { gcode_M914(); break; #endif + + #if ENABLED(TMC_Z_CALIBRATION) && (Z_IS_TRINAMIC || Z2_IS_TRINAMIC) + case 915: // M915: TMC Z axis calibration routine + gcode_M915(); + break; + #endif #endif #if HAS_MICROSTEPS @@ -11691,6 +12463,23 @@ void process_next_command() { ok_to_send(); } +void process_next_command() { + char * const current_command = command_queue[cmd_queue_index_r]; + + if (DEBUGGING(ECHO)) { + SERIAL_ECHO_START(); + SERIAL_ECHOLN(current_command); + #if ENABLED(M100_FREE_MEMORY_WATCHER) + SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); + M100_dump_routine(" Command Queue:", (const char*)command_queue, (const char*)(command_queue + sizeof(command_queue))); + #endif + } + + // Parse the next command in the queue + parser.parse(current_command); + process_parsed_command(); +} + /** * Send a "Resend: nnn" message to the host to * indicate that a command needs to be re-sent. @@ -11734,29 +12523,37 @@ void ok_to_send() { /** * Constrain the given coordinates to the software endstops. + * + * For DELTA/SCARA the XY constraint is based on the smallest + * radius within the set software endstops. */ - - // NOTE: This makes no sense for delta beds other than Z-axis. - // For delta the X/Y would need to be clamped at - // DELTA_PRINTABLE_RADIUS from center of bed, but delta - // now enforces is_position_reachable for X/Y regardless - // of HAS_SOFTWARE_ENDSTOPS, so that enforcement would be - // redundant here. - void clamp_to_software_endstops(float target[XYZ]) { if (!soft_endstops_enabled) return; - #if ENABLED(MIN_SOFTWARE_ENDSTOPS) - #if DISABLED(DELTA) + #if IS_KINEMATIC + const float dist_2 = HYPOT2(target[X_AXIS], target[Y_AXIS]); + if (dist_2 > soft_endstop_radius_2) { + const float ratio = soft_endstop_radius / SQRT(dist_2); // 200 / 300 = 0.66 + target[X_AXIS] *= ratio; + target[Y_AXIS] *= ratio; + } + #else + #if ENABLED(MIN_SOFTWARE_ENDSTOP_X) NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]); + #endif + #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]); #endif - NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]); - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOPS) - #if DISABLED(DELTA) + #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]); + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]); #endif + #endif + #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z) + NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]); + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]); #endif } @@ -11780,7 +12577,7 @@ void ok_to_send() { #endif // Get the Z adjustment for non-linear bed leveling - float bilinear_z_offset(const float logical[XYZ]) { + float bilinear_z_offset(const float raw[XYZ]) { static float z1, d2, z3, d4, L, D, ratio_x, ratio_y, last_x = -999.999, last_y = -999.999; @@ -11790,8 +12587,8 @@ void ok_to_send() { last_gridx = -99, last_gridy = -99; // XY relative to the probed area - const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS], - y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS]; + const float rx = raw[X_AXIS] - bilinear_start[X_AXIS], + ry = raw[Y_AXIS] - bilinear_start[Y_AXIS]; #if ENABLED(EXTRAPOLATE_BEYOND_GRID) // Keep using the last grid box @@ -11801,9 +12598,9 @@ void ok_to_send() { #define FAR_EDGE_OR_BOX 1 #endif - if (last_x != x) { - last_x = x; - ratio_x = x * ABL_BG_FACTOR(X_AXIS); + if (last_x != rx) { + last_x = rx; + ratio_x = rx * ABL_BG_FACTOR(X_AXIS); const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX); ratio_x -= gx; // Subtract whole to get the ratio within the grid box @@ -11816,11 +12613,11 @@ void ok_to_send() { nextx = min(gridx + 1, ABL_BG_POINTS_X - 1); } - if (last_y != y || last_gridx != gridx) { + if (last_y != ry || last_gridx != gridx) { - if (last_y != y) { - last_y = y; - ratio_y = y * ABL_BG_FACTOR(Y_AXIS); + if (last_y != ry) { + last_y = ry; + ratio_y = ry * ABL_BG_FACTOR(Y_AXIS); const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX); ratio_y -= gy; @@ -11843,7 +12640,7 @@ void ok_to_send() { d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta) } - // Bilinear interpolate. Needed since y or gridx has changed. + // Bilinear interpolate. Needed since ry or gridx has changed. L = z1 + d2 * ratio_y; // Linear interp. LF -> LB const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB @@ -11856,10 +12653,10 @@ void ok_to_send() { static float last_offset = 0; if (FABS(last_offset - offset) > 0.2) { SERIAL_ECHOPGM("Sudden Shift at "); - SERIAL_ECHOPAIR("x=", x); + SERIAL_ECHOPAIR("x=", rx); SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]); SERIAL_ECHOLNPAIR(" -> gridx=", gridx); - SERIAL_ECHOPAIR(" y=", y); + SERIAL_ECHOPAIR(" y=", ry); SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]); SERIAL_ECHOLNPAIR(" -> gridy=", gridy); SERIAL_ECHOPAIR(" ratio_x=", ratio_x); @@ -11886,18 +12683,20 @@ void ok_to_send() { * Recalculate factors used for delta kinematics whenever * settings have been changed (e.g., by M665). */ - void recalc_delta_settings(float radius, float diagonal_rod, float tower_angle_trim[ABC]) { + void recalc_delta_settings() { const float trt[ABC] = DELTA_RADIUS_TRIM_TOWER, drt[ABC] = DELTA_DIAGONAL_ROD_TRIM_TOWER; - delta_tower[A_AXIS][X_AXIS] = cos(RADIANS(210 + tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]); // front left tower - delta_tower[A_AXIS][Y_AXIS] = sin(RADIANS(210 + tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]); - delta_tower[B_AXIS][X_AXIS] = cos(RADIANS(330 + tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]); // front right tower - delta_tower[B_AXIS][Y_AXIS] = sin(RADIANS(330 + tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]); - delta_tower[C_AXIS][X_AXIS] = cos(RADIANS( 90 + tower_angle_trim[C_AXIS])) * (radius + trt[C_AXIS]); // back middle tower - delta_tower[C_AXIS][Y_AXIS] = sin(RADIANS( 90 + tower_angle_trim[C_AXIS])) * (radius + trt[C_AXIS]); - delta_diagonal_rod_2_tower[A_AXIS] = sq(diagonal_rod + drt[A_AXIS]); - delta_diagonal_rod_2_tower[B_AXIS] = sq(diagonal_rod + drt[B_AXIS]); - delta_diagonal_rod_2_tower[C_AXIS] = sq(diagonal_rod + drt[C_AXIS]); + delta_tower[A_AXIS][X_AXIS] = cos(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (delta_radius + trt[A_AXIS]); // front left tower + delta_tower[A_AXIS][Y_AXIS] = sin(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (delta_radius + trt[A_AXIS]); + delta_tower[B_AXIS][X_AXIS] = cos(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (delta_radius + trt[B_AXIS]); // front right tower + delta_tower[B_AXIS][Y_AXIS] = sin(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (delta_radius + trt[B_AXIS]); + delta_tower[C_AXIS][X_AXIS] = cos(RADIANS( 90 + delta_tower_angle_trim[C_AXIS])) * (delta_radius + trt[C_AXIS]); // back middle tower + delta_tower[C_AXIS][Y_AXIS] = sin(RADIANS( 90 + delta_tower_angle_trim[C_AXIS])) * (delta_radius + trt[C_AXIS]); + delta_diagonal_rod_2_tower[A_AXIS] = sq(delta_diagonal_rod + drt[A_AXIS]); + delta_diagonal_rod_2_tower[B_AXIS] = sq(delta_diagonal_rod + drt[B_AXIS]); + delta_diagonal_rod_2_tower[C_AXIS] = sq(delta_diagonal_rod + drt[C_AXIS]); + update_software_endstops(Z_AXIS); + axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; } #if ENABLED(DELTA_FAST_SQRT) @@ -11905,7 +12704,7 @@ void ok_to_send() { * Fast inverse sqrt from Quake III Arena * See: https://en.wikipedia.org/wiki/Fast_inverse_square_root */ - float Q_rsqrt(float number) { + float Q_rsqrt(const float number) { long i; float x2, y; const float threehalfs = 1.5f; @@ -11919,18 +12718,12 @@ void ok_to_send() { return y; } - #define _SQRT(n) (1.0f / Q_rsqrt(n)) - - #else - - #define _SQRT(n) SQRT(n) - #endif /** * Delta Inverse Kinematics * - * Calculate the tower positions for a given logical + * Calculate the tower positions for a given machine * position, storing the result in the delta[] array. * * This is an expensive calculation, requiring 3 square @@ -11946,29 +12739,6 @@ void ok_to_send() { * (see above) */ - // Macro to obtain the Z position of an individual tower - #define DELTA_Z(T) raw[Z_AXIS] + _SQRT( \ - delta_diagonal_rod_2_tower[T] - HYPOT2( \ - delta_tower[T][X_AXIS] - raw[X_AXIS], \ - delta_tower[T][Y_AXIS] - raw[Y_AXIS] \ - ) \ - ) - - #define DELTA_RAW_IK() do { \ - delta[A_AXIS] = DELTA_Z(A_AXIS); \ - delta[B_AXIS] = DELTA_Z(B_AXIS); \ - delta[C_AXIS] = DELTA_Z(C_AXIS); \ - }while(0) - - #define DELTA_LOGICAL_IK() do { \ - const float raw[XYZ] = { \ - RAW_X_POSITION(logical[X_AXIS]), \ - RAW_Y_POSITION(logical[Y_AXIS]), \ - RAW_Z_POSITION(logical[Z_AXIS]) \ - }; \ - DELTA_RAW_IK(); \ - }while(0) - #define DELTA_DEBUG() do { \ SERIAL_ECHOPAIR("cartesian X:", raw[X_AXIS]); \ SERIAL_ECHOPAIR(" Y:", raw[Y_AXIS]); \ @@ -11978,8 +12748,8 @@ void ok_to_send() { SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \ }while(0) - void inverse_kinematics(const float logical[XYZ]) { - DELTA_LOGICAL_IK(); + void inverse_kinematics(const float raw[XYZ]) { + DELTA_RAW_IK(); // DELTA_DEBUG(); } @@ -11988,14 +12758,10 @@ void ok_to_send() { * effector has the full range of XY motion. */ float delta_safe_distance_from_top() { - float cartesian[XYZ] = { - LOGICAL_X_POSITION(0), - LOGICAL_Y_POSITION(0), - LOGICAL_Z_POSITION(0) - }; + float cartesian[XYZ] = { 0, 0, 0 }; inverse_kinematics(cartesian); float distance = delta[A_AXIS]; - cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS); + cartesian[Y_AXIS] = DELTA_PRINTABLE_RADIUS; inverse_kinematics(cartesian); return FABS(distance - delta[A_AXIS]); } @@ -12027,46 +12793,53 @@ void ok_to_send() { */ void forward_kinematics_DELTA(float z1, float z2, float z3) { // Create a vector in old coordinates along x axis of new coordinate - float p12[3] = { delta_tower[B_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[B_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z2 - z1 }; + const float p12[] = { + delta_tower[B_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], + delta_tower[B_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], + z2 - z1 + }, // Get the Magnitude of vector. - float d = SQRT( sq(p12[0]) + sq(p12[1]) + sq(p12[2]) ); + d = SQRT(sq(p12[0]) + sq(p12[1]) + sq(p12[2])), // Create unit vector by dividing by magnitude. - float ex[3] = { p12[0] / d, p12[1] / d, p12[2] / d }; + ex[3] = { p12[0] / d, p12[1] / d, p12[2] / d }, // Get the vector from the origin of the new system to the third point. - float p13[3] = { delta_tower[C_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[C_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z3 - z1 }; + p13[3] = { + delta_tower[C_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], + delta_tower[C_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], + z3 - z1 + }, // Use the dot product to find the component of this vector on the X axis. - float i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2]; + i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2], // Create a vector along the x axis that represents the x component of p13. - float iex[3] = { ex[0] * i, ex[1] * i, ex[2] * i }; + iex[] = { ex[0] * i, ex[1] * i, ex[2] * i }; // Subtract the X component from the original vector leaving only Y. We use the // variable that will be the unit vector after we scale it. float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2] }; // The magnitude of Y component - float j = SQRT( sq(ey[0]) + sq(ey[1]) + sq(ey[2]) ); + const float j = SQRT(sq(ey[0]) + sq(ey[1]) + sq(ey[2])); // Convert to a unit vector ey[0] /= j; ey[1] /= j; ey[2] /= j; // The cross product of the unit x and y is the unit z // float[] ez = vectorCrossProd(ex, ey); - float ez[3] = { + const float ez[3] = { ex[1] * ey[2] - ex[2] * ey[1], ex[2] * ey[0] - ex[0] * ey[2], ex[0] * ey[1] - ex[1] * ey[0] - }; - + }, // We now have the d, i and j values defined in Wikipedia. // Plug them into the equations defined in Wikipedia for Xnew, Ynew and Znew - float Xnew = (delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[B_AXIS] + sq(d)) / (d * 2), - Ynew = ((delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[C_AXIS] + HYPOT2(i, j)) / 2 - i * Xnew) / j, - Znew = SQRT(delta_diagonal_rod_2_tower[A_AXIS] - HYPOT2(Xnew, Ynew)); + Xnew = (delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[B_AXIS] + sq(d)) / (d * 2), + Ynew = ((delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[C_AXIS] + HYPOT2(i, j)) / 2 - i * Xnew) / j, + Znew = SQRT(delta_diagonal_rod_2_tower[A_AXIS] - HYPOT2(Xnew, Ynew)); // Start from the origin of the old coordinates and add vectors in the // old coords that represent the Xnew, Ynew and Znew to find the point @@ -12088,8 +12861,8 @@ void ok_to_send() { * * The result is in the current coordinate space with * leveling applied. The coordinates need to be run through - * unapply_leveling to obtain the "ideal" coordinates - * suitable for current_position, etc. + * unapply_leveling to obtain machine coordinates suitable + * for current_position, etc. */ void get_cartesian_from_steppers() { #if ENABLED(DELTA) @@ -12098,20 +12871,16 @@ void get_cartesian_from_steppers() { stepper.get_axis_position_mm(B_AXIS), stepper.get_axis_position_mm(C_AXIS) ); - cartes[X_AXIS] += LOGICAL_X_POSITION(0); - cartes[Y_AXIS] += LOGICAL_Y_POSITION(0); - cartes[Z_AXIS] += LOGICAL_Z_POSITION(0); - #elif IS_SCARA - forward_kinematics_SCARA( - stepper.get_axis_position_degrees(A_AXIS), - stepper.get_axis_position_degrees(B_AXIS) - ); - cartes[X_AXIS] += LOGICAL_X_POSITION(0); - cartes[Y_AXIS] += LOGICAL_Y_POSITION(0); - cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); #else - cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); - cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); + #if IS_SCARA + forward_kinematics_SCARA( + stepper.get_axis_position_degrees(A_AXIS), + stepper.get_axis_position_degrees(B_AXIS) + ); + #else + cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); + cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); + #endif cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); #endif } @@ -12120,6 +12889,12 @@ void get_cartesian_from_steppers() { * Set the current_position for an axis based on * the stepper positions, removing any leveling that * may have been applied. + * + * To prevent small shifts in axis position always call + * SYNC_PLAN_POSITION_KINEMATIC after updating axes with this. + * + * To keep hosts in sync, always call report_current_position + * after updating the current_position. */ void set_current_from_steppers_for_axis(const AxisEnum axis) { get_cartesian_from_steppers(); @@ -12132,53 +12907,129 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { current_position[axis] = cartes[axis]; } -#if ENABLED(MESH_BED_LEVELING) +#if IS_CARTESIAN +#if ENABLED(SEGMENT_LEVELED_MOVES) + + /** + * Prepare a segmented move on a CARTESIAN setup. + * + * This calls planner.buffer_line several times, adding + * small incremental moves. This allows the planner to + * apply more detailed bed leveling to the full move. + */ + inline void segmented_line_to_destination(const float &fr_mm_s, const float segment_size=LEVELED_SEGMENT_LENGTH) { + + const float xdiff = destination[X_AXIS] - current_position[X_AXIS], + ydiff = destination[Y_AXIS] - current_position[Y_AXIS]; + + // If the move is only in Z/E don't split up the move + if (!xdiff && !ydiff) { + planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder); + return; + } + + // Remaining cartesian distances + const float zdiff = destination[Z_AXIS] - current_position[Z_AXIS], + ediff = destination[E_AXIS] - current_position[E_AXIS]; + + // Get the linear distance in XYZ + // If the move is very short, check the E move distance + // No E move either? Game over. + float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff)); + if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = FABS(ediff); + if (UNEAR_ZERO(cartesian_mm)) return; + + // The length divided by the segment size + // At least one segment is required + uint16_t segments = cartesian_mm / segment_size; + NOLESS(segments, 1); + + // The approximate length of each segment + const float inv_segments = 1.0 / float(segments), + segment_distance[XYZE] = { + xdiff * inv_segments, + ydiff * inv_segments, + zdiff * inv_segments, + ediff * inv_segments + }; + + // SERIAL_ECHOPAIR("mm=", cartesian_mm); + // SERIAL_ECHOLNPAIR(" segments=", segments); + + // Get the raw current position as starting point + float raw[XYZE]; + COPY(raw, current_position); + + // Calculate and execute the segments + while (--segments) { + static millis_t next_idle_ms = millis() + 200UL; + thermalManager.manage_heater(); // This returns immediately if not really needed. + if (ELAPSED(millis(), next_idle_ms)) { + next_idle_ms = millis() + 200UL; + idle(); + } + LOOP_XYZE(i) raw[i] += segment_distance[i]; + planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder); + } + + // Since segment_distance is only approximate, + // the final move must be to the exact destination. + planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder); + } + +#elif ENABLED(MESH_BED_LEVELING) /** * Prepare a mesh-leveled linear move in a Cartesian setup, * splitting the move where it crosses mesh borders. */ - void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xFF, uint8_t y_splits = 0xFF) { - int cx1 = mbl.cell_index_x(RAW_CURRENT_POSITION(X)), - cy1 = mbl.cell_index_y(RAW_CURRENT_POSITION(Y)), - cx2 = mbl.cell_index_x(RAW_X_POSITION(destination[X_AXIS])), - cy2 = mbl.cell_index_y(RAW_Y_POSITION(destination[Y_AXIS])); + void mesh_line_to_destination(const float fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF) { + // Get current and destination cells for this line + int cx1 = mbl.cell_index_x(current_position[X_AXIS]), + cy1 = mbl.cell_index_y(current_position[Y_AXIS]), + cx2 = mbl.cell_index_x(destination[X_AXIS]), + cy2 = mbl.cell_index_y(destination[Y_AXIS]); NOMORE(cx1, GRID_MAX_POINTS_X - 2); NOMORE(cy1, GRID_MAX_POINTS_Y - 2); NOMORE(cx2, GRID_MAX_POINTS_X - 2); NOMORE(cy2, GRID_MAX_POINTS_Y - 2); + // Start and end in the same cell? No split needed. if (cx1 == cx2 && cy1 == cy2) { - // Start and end on same mesh square - line_to_destination(fr_mm_s); - set_current_to_destination(); + buffer_line_to_destination(fr_mm_s); + set_current_from_destination(); return; } #define MBL_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist) float normalized_dist, end[XYZE]; - - // Split at the left/front border of the right/top square const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); + + // Crosses on the X and not already split on this X? + // The x_splits flags are insurance against rounding errors. if (cx2 != cx1 && TEST(x_splits, gcx)) { + // Split on the X grid line + CBI(x_splits, gcx); COPY(end, destination); - destination[X_AXIS] = LOGICAL_X_POSITION(mbl.index_to_xpos[gcx]); + destination[X_AXIS] = mbl.index_to_xpos[gcx]; normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]); destination[Y_AXIS] = MBL_SEGMENT_END(Y); - CBI(x_splits, gcx); } + // Crosses on the Y and not already split on this Y? else if (cy2 != cy1 && TEST(y_splits, gcy)) { + // Split on the Y grid line + CBI(y_splits, gcy); COPY(end, destination); - destination[Y_AXIS] = LOGICAL_Y_POSITION(mbl.index_to_ypos[gcy]); + destination[Y_AXIS] = mbl.index_to_ypos[gcy]; normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]); destination[X_AXIS] = MBL_SEGMENT_END(X); - CBI(y_splits, gcy); } else { - // Already split on a border - line_to_destination(fr_mm_s); - set_current_to_destination(); + // Must already have been split on these border(s) + // This should be a rare case. + buffer_line_to_destination(fr_mm_s); + set_current_from_destination(); return; } @@ -12193,15 +13044,16 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { mesh_line_to_destination(fr_mm_s, x_splits, y_splits); } -#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) && !IS_KINEMATIC +#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - #define CELL_INDEX(A,V) ((RAW_##A##_POSITION(V) - bilinear_start[A##_AXIS]) * ABL_BG_FACTOR(A##_AXIS)) + #define CELL_INDEX(A,V) ((V - bilinear_start[A##_AXIS]) * ABL_BG_FACTOR(A##_AXIS)) /** * Prepare a bilinear-leveled linear move on Cartesian, * splitting the move where it crosses grid borders. */ - void bilinear_line_to_destination(float fr_mm_s, uint16_t x_splits = 0xFFFF, uint16_t y_splits = 0xFFFF) { + void bilinear_line_to_destination(const float fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF) { + // Get current and destination cells for this line int cx1 = CELL_INDEX(X, current_position[X_AXIS]), cy1 = CELL_INDEX(Y, current_position[Y_AXIS]), cx2 = CELL_INDEX(X, destination[X_AXIS]), @@ -12211,37 +13063,42 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { cx2 = constrain(cx2, 0, ABL_BG_POINTS_X - 2); cy2 = constrain(cy2, 0, ABL_BG_POINTS_Y - 2); + // Start and end in the same cell? No split needed. if (cx1 == cx2 && cy1 == cy2) { - // Start and end on same mesh square - line_to_destination(fr_mm_s); - set_current_to_destination(); + buffer_line_to_destination(fr_mm_s); + set_current_from_destination(); return; } #define LINE_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist) float normalized_dist, end[XYZE]; - - // Split at the left/front border of the right/top square const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); + + // Crosses on the X and not already split on this X? + // The x_splits flags are insurance against rounding errors. if (cx2 != cx1 && TEST(x_splits, gcx)) { + // Split on the X grid line + CBI(x_splits, gcx); COPY(end, destination); - destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx); + destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx; normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]); destination[Y_AXIS] = LINE_SEGMENT_END(Y); - CBI(x_splits, gcx); } + // Crosses on the Y and not already split on this Y? else if (cy2 != cy1 && TEST(y_splits, gcy)) { + // Split on the Y grid line + CBI(y_splits, gcy); COPY(end, destination); - destination[Y_AXIS] = LOGICAL_Y_POSITION(bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy); + destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy; normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]); destination[X_AXIS] = LINE_SEGMENT_END(X); - CBI(y_splits, gcy); } else { - // Already split on a border - line_to_destination(fr_mm_s); - set_current_to_destination(); + // Must already have been split on these border(s) + // This should be a rare case. + buffer_line_to_destination(fr_mm_s); + set_current_from_destination(); return; } @@ -12257,44 +13114,46 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { } #endif // AUTO_BED_LEVELING_BILINEAR +#endif // IS_CARTESIAN -#if IS_KINEMATIC && !UBL_DELTA +#if !UBL_SEGMENTED +#if IS_KINEMATIC /** * Prepare a linear move in a DELTA or SCARA setup. * * This calls planner.buffer_line several times, adding * small incremental moves for DELTA or SCARA. + * + * For Unified Bed Leveling (Delta or Segmented Cartesian) + * the ubl.prepare_segmented_line_to method replaces this. */ - inline bool prepare_kinematic_move_to(float ltarget[XYZE]) { + inline bool prepare_kinematic_move_to(const float (&rtarget)[XYZE]) { // Get the top feedrate of the move in the XY plane const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s); + const float xdiff = rtarget[X_AXIS] - current_position[X_AXIS], + ydiff = rtarget[Y_AXIS] - current_position[Y_AXIS]; + // If the move is only in Z/E don't split up the move - if (ltarget[X_AXIS] == current_position[X_AXIS] && ltarget[Y_AXIS] == current_position[Y_AXIS]) { - planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); + if (!xdiff && !ydiff) { + planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder); return false; } // Fail if attempting move outside printable radius - if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) return true; + if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) return true; - // Get the cartesian distances moved in XYZE - const float difference[XYZE] = { - ltarget[X_AXIS] - current_position[X_AXIS], - ltarget[Y_AXIS] - current_position[Y_AXIS], - ltarget[Z_AXIS] - current_position[Z_AXIS], - ltarget[E_AXIS] - current_position[E_AXIS] - }; + // Remaining cartesian distances + const float zdiff = rtarget[Z_AXIS] - current_position[Z_AXIS], + ediff = rtarget[E_AXIS] - current_position[E_AXIS]; // Get the linear distance in XYZ - float cartesian_mm = SQRT(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); - // If the move is very short, check the E move distance - if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = FABS(difference[E_AXIS]); - // No E move either? Game over. + float cartesian_mm = SQRT(sq(xdiff) + sq(ydiff) + sq(zdiff)); + if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = FABS(ediff); if (UNEAR_ZERO(cartesian_mm)) return true; // Minimum number of seconds to move the given distance @@ -12315,10 +13174,10 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { // The approximate length of each segment const float inv_segments = 1.0 / float(segments), segment_distance[XYZE] = { - difference[X_AXIS] * inv_segments, - difference[Y_AXIS] * inv_segments, - difference[Z_AXIS] * inv_segments, - difference[E_AXIS] * inv_segments + xdiff * inv_segments, + ydiff * inv_segments, + zdiff * inv_segments, + ediff * inv_segments }; // SERIAL_ECHOPAIR("mm=", cartesian_mm); @@ -12328,40 +13187,45 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) // SCARA needs to scale the feed rate from mm/s to degrees/s const float inv_segment_length = min(10.0, float(segments) / cartesian_mm), // 1/mm/segs - feed_factor = inv_segment_length * _feedrate_mm_s; + inverse_secs = inv_segment_length * _feedrate_mm_s; float oldA = stepper.get_axis_position_degrees(A_AXIS), oldB = stepper.get_axis_position_degrees(B_AXIS); #endif - // Get the logical current position as starting point - float logical[XYZE]; - COPY(logical, current_position); + // Get the current position as starting point + float raw[XYZE]; + COPY(raw, current_position); - // Drop one segment so the last move is to the exact target. - // If there's only 1 segment, loops will be skipped entirely. - --segments; // Calculate and execute the segments - for (uint16_t s = segments + 1; --s;) { - LOOP_XYZE(i) logical[i] += segment_distance[i]; + while (--segments) { + + static millis_t next_idle_ms = millis() + 200UL; + thermalManager.manage_heater(); // This returns immediately if not really needed. + if (ELAPSED(millis(), next_idle_ms)) { + next_idle_ms = millis() + 200UL; + idle(); + } + + LOOP_XYZE(i) raw[i] += segment_distance[i]; #if ENABLED(DELTA) - DELTA_LOGICAL_IK(); // Delta can inline its kinematics + DELTA_RAW_IK(); // Delta can inline its kinematics #else - inverse_kinematics(logical); + inverse_kinematics(raw); #endif - ADJUST_DELTA(logical); // Adjust Z if bed leveling is enabled + ADJUST_DELTA(raw); // Adjust Z if bed leveling is enabled #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) // For SCARA scale the feed rate from mm/s to degrees/s // Use ratio between the length of the move and the larger angle change const float adiff = abs(delta[A_AXIS] - oldA), bdiff = abs(delta[B_AXIS] - oldB); - planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], max(adiff, bdiff) * inverse_secs, active_extruder); oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; #else - planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], _feedrate_mm_s, active_extruder); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], _feedrate_mm_s, active_extruder); #endif } @@ -12371,79 +13235,79 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) // For SCARA scale the feed rate from mm/s to degrees/s // With segments > 1 length is 1 segment, otherwise total length - inverse_kinematics(ltarget); - ADJUST_DELTA(ltarget); + inverse_kinematics(rtarget); + ADJUST_DELTA(rtarget); const float adiff = abs(delta[A_AXIS] - oldA), bdiff = abs(delta[B_AXIS] - oldB); - planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], max(adiff, bdiff) * inverse_secs, active_extruder); #else - planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); + planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder); #endif return false; } -#else // !IS_KINEMATIC || UBL_DELTA +#else // !IS_KINEMATIC /** * Prepare a linear move in a Cartesian setup. - * If Mesh Bed Leveling is enabled, perform a mesh move. * - * Returns true if the caller didn't update current_position. + * When a mesh-based leveling system is active, moves are segmented + * according to the configuration of the leveling system. + * + * Returns true if current_position[] was set to destination[] */ inline bool prepare_move_to_destination_cartesian() { - #if ENABLED(AUTO_BED_LEVELING_UBL) - const float fr_scaled = MMS_SCALED(feedrate_mm_s); - if (ubl.state.active) { // direct use of ubl.state.active for speed - ubl.line_to_destination_cartesian(fr_scaled, active_extruder); - return true; - } - else - line_to_destination(fr_scaled); - #else - // Do not use feedrate_percentage for E or Z only moves - if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) - line_to_destination(); - else { - const float fr_scaled = MMS_SCALED(feedrate_mm_s); - #if ENABLED(MESH_BED_LEVELING) - if (mbl.active()) { // direct used of mbl.active() for speed - mesh_line_to_destination(fr_scaled); + #if HAS_MESH + if (planner.leveling_active && planner.leveling_active_at_z(destination[Z_AXIS])) { + #if ENABLED(AUTO_BED_LEVELING_UBL) + ubl.line_to_destination_cartesian(MMS_SCALED(feedrate_mm_s), active_extruder); // UBL's motion routine needs to know about + return true; // all moves, including Z-only moves. + #elif ENABLED(SEGMENT_LEVELED_MOVES) + segmented_line_to_destination(MMS_SCALED(feedrate_mm_s)); + return false; + #else + /** + * For MBL and ABL-BILINEAR only segment moves when X or Y are involved. + * Otherwise fall through to do a direct single move. + */ + if (current_position[X_AXIS] != destination[X_AXIS] || current_position[Y_AXIS] != destination[Y_AXIS]) { + #if ENABLED(MESH_BED_LEVELING) + mesh_line_to_destination(MMS_SCALED(feedrate_mm_s)); + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + bilinear_line_to_destination(MMS_SCALED(feedrate_mm_s)); + #endif return true; } - else - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - if (planner.abl_enabled) { // direct use of abl_enabled for speed - bilinear_line_to_destination(fr_scaled); - return true; - } - else #endif - line_to_destination(fr_scaled); } - #endif + #endif // HAS_MESH + + buffer_line_to_destination(MMS_SCALED(feedrate_mm_s)); return false; } -#endif // !IS_KINEMATIC || UBL_DELTA +#endif // !IS_KINEMATIC +#endif // !UBL_SEGMENTED #if ENABLED(DUAL_X_CARRIAGE) /** - * Prepare a linear move in a dual X axis setup + * Unpark the carriage, if needed */ - inline bool prepare_move_to_destination_dualx() { - if (active_extruder_parked) { + inline bool dual_x_carriage_unpark() { + if (active_extruder_parked) switch (dual_x_carriage_mode) { - case DXC_FULL_CONTROL_MODE: - break; + + case DXC_FULL_CONTROL_MODE: break; + case DXC_AUTO_PARK_MODE: if (current_position[E_AXIS] == destination[E_AXIS]) { // This is a travel move (with no extrusion) // Skip it, but keep track of the current position // (so it can be used as the start of the next non-travel move) if (delayed_move_time != 0xFFFFFFFFUL) { - set_current_to_destination(); + set_current_from_destination(); NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]); delayed_move_time = millis(); return true; @@ -12465,17 +13329,18 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Clear active_extruder_parked"); #endif break; + case DXC_DUPLICATION_MODE: if (active_extruder == 0) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { - SERIAL_ECHOPAIR("Set planner X", LOGICAL_X_POSITION(inactive_extruder_x_pos)); + SERIAL_ECHOPAIR("Set planner X", inactive_extruder_x_pos); SERIAL_ECHOLNPAIR(" ... Line to X", current_position[X_AXIS] + duplicate_extruder_x_offset); } #endif // move duplicate extruder into correct duplication position. planner.set_position_mm( - LOGICAL_X_POSITION(inactive_extruder_x_pos), + inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] @@ -12500,8 +13365,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { } break; } - } - return prepare_move_to_destination_cartesian(); + return false; } #endif // DUAL_X_CARRIAGE @@ -12511,45 +13375,52 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { * * This may result in several calls to planner.buffer_line to * do smaller moves for DELTA, SCARA, mesh moves, etc. + * + * Make sure current_position[E] and destination[E] are good + * before calling or cold/lengthy extrusion may get missed. */ void prepare_move_to_destination() { clamp_to_software_endstops(destination); refresh_cmd_timeout(); - #if ENABLED(PREVENT_COLD_EXTRUSION) + #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) if (!DEBUGGING(DRYRUN)) { if (destination[E_AXIS] != current_position[E_AXIS]) { - if (thermalManager.tooColdToExtrude(active_extruder)) { - current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part - SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); - } + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.tooColdToExtrude(active_extruder)) { + current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (destination[E_AXIS] - current_position[E_AXIS] > EXTRUDE_MAXLENGTH) { + if (FABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder] > (EXTRUDE_MAXLENGTH)) { current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); } - #endif + #endif // PREVENT_LENGTHY_EXTRUDE } } #endif + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_unpark()) return; + #endif + if ( - #if UBL_DELTA // Also works for CARTESIAN (smaller segments follow mesh more closely) - ubl.prepare_segmented_line_to(destination, feedrate_mm_s) + #if UBL_SEGMENTED + ubl.prepare_segmented_line_to(destination, MMS_SCALED(feedrate_mm_s)) #elif IS_KINEMATIC prepare_kinematic_move_to(destination) - #elif ENABLED(DUAL_X_CARRIAGE) - prepare_move_to_destination_dualx() #else prepare_move_to_destination_cartesian() #endif ) return; - set_current_to_destination(); + set_current_from_destination(); } #if ENABLED(ARC_SUPPORT) @@ -12569,13 +13440,14 @@ void prepare_move_to_destination() { * options for G2/G3 arc generation. In future these options may be GCode tunable. */ void plan_arc( - float logical[XYZE], // Destination position - float *offset, // Center of rotation relative to current_position - uint8_t clockwise // Clockwise? + const float (&cart)[XYZE], // Destination position + const float (&offset)[2], // Center of rotation relative to current_position + const bool clockwise // Clockwise? ) { #if ENABLED(CNC_WORKSPACE_PLANES) AxisEnum p_axis, q_axis, l_axis; switch (workspace_plane) { + default: case PLANE_XY: p_axis = X_AXIS; q_axis = Y_AXIS; l_axis = Z_AXIS; break; case PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break; case PLANE_YZ: p_axis = Y_AXIS; q_axis = Z_AXIS; l_axis = X_AXIS; break; @@ -12590,10 +13462,10 @@ void prepare_move_to_destination() { const float radius = HYPOT(r_P, r_Q), center_P = current_position[p_axis] - r_P, center_Q = current_position[q_axis] - r_Q, - rt_X = logical[p_axis] - center_P, - rt_Y = logical[q_axis] - center_Q, - linear_travel = logical[l_axis] - current_position[l_axis], - extruder_travel = logical[E_AXIS] - current_position[E_AXIS]; + rt_X = cart[p_axis] - center_P, + rt_Y = cart[q_axis] - center_Q, + linear_travel = cart[l_axis] - current_position[l_axis], + extruder_travel = cart[E_AXIS] - current_position[E_AXIS]; // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required. float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y); @@ -12601,14 +13473,14 @@ void prepare_move_to_destination() { if (clockwise) angular_travel -= RADIANS(360); // Make a circle if the angular rotation is 0 and the target is current position - if (angular_travel == 0 && current_position[p_axis] == logical[p_axis] && current_position[q_axis] == logical[q_axis]) + if (angular_travel == 0 && current_position[p_axis] == cart[p_axis] && current_position[q_axis] == cart[q_axis]) angular_travel = RADIANS(360); const float mm_of_travel = HYPOT(angular_travel * radius, FABS(linear_travel)); if (mm_of_travel < 0.001) return; uint16_t segments = FLOOR(mm_of_travel / (MM_PER_ARC_SEGMENT)); - if (segments == 0) segments = 1; + NOLESS(segments, 1); /** * Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, @@ -12701,25 +13573,25 @@ void prepare_move_to_destination() { } // Ensure last segment arrives at target location. - planner.buffer_line_kinematic(logical, fr_mm_s, active_extruder); + planner.buffer_line_kinematic(cart, fr_mm_s, active_extruder); // As far as the parser is concerned, the position is now == target. In reality the // motion control system might still be processing the action and the real tool position // in any intermediate location. - set_current_to_destination(); + set_current_from_destination(); } // plan_arc #endif // ARC_SUPPORT #if ENABLED(BEZIER_CURVE_SUPPORT) - void plan_cubic_move(const float offset[4]) { + void plan_cubic_move(const float (&offset)[4]) { cubic_b_spline(current_position, destination, offset, MMS_SCALED(feedrate_mm_s), active_extruder); // As far as the parser is concerned, the position is now == destination. In reality the // motion control system might still be processing the action and the real tool position // in any intermediate location. - set_current_to_destination(); + set_current_from_destination(); } #endif // BEZIER_CURVE_SUPPORT @@ -12801,12 +13673,12 @@ void prepare_move_to_destination() { * Maths and first version by QHARLEY. * Integrated into Marlin and slightly restructured by Joachim Cerny. */ - void inverse_kinematics(const float logical[XYZ]) { + void inverse_kinematics(const float raw[XYZ]) { static float C2, S2, SK1, SK2, THETA, PSI; - float sx = RAW_X_POSITION(logical[X_AXIS]) - SCARA_OFFSET_X, // Translate SCARA to standard X Y - sy = RAW_Y_POSITION(logical[Y_AXIS]) - SCARA_OFFSET_Y; // With scaling factor. + float sx = raw[X_AXIS] - SCARA_OFFSET_X, // Translate SCARA to standard X Y + sy = raw[Y_AXIS] - SCARA_OFFSET_Y; // With scaling factor. if (L1 == L2) C2 = HYPOT2(sx, sy) / L1_2_2 - 1; @@ -12829,10 +13701,10 @@ void prepare_move_to_destination() { delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor) - delta[C_AXIS] = logical[Z_AXIS]; + delta[C_AXIS] = raw[Z_AXIS]; /* - DEBUG_POS("SCARA IK", logical); + DEBUG_POS("SCARA IK", raw); DEBUG_POS("SCARA IK", delta); SERIAL_ECHOPAIR(" SCARA (x,y) ", sx); SERIAL_ECHOPAIR(",", sy); @@ -12897,64 +13769,36 @@ void prepare_move_to_destination() { #if !AVR_AT90USB1286_FAMILY case TIMER0A: #endif - case TIMER0B: - //_SET_CS(0, val); - break; + case TIMER0B: //_SET_CS(0, val); + break; #endif #ifdef TCCR1A - case TIMER1A: - case TIMER1B: - //_SET_CS(1, val); - break; + case TIMER1A: case TIMER1B: //_SET_CS(1, val); + break; #endif - #ifdef TCCR2 - case TIMER2: - case TIMER2: - _SET_CS(2, val); - break; - #endif - #ifdef TCCR2A - case TIMER2A: - case TIMER2B: - _SET_CS(2, val); - break; + #if defined(TCCR2) || defined(TCCR2A) + #ifdef TCCR2 + case TIMER2: + #endif + #ifdef TCCR2A + case TIMER2A: case TIMER2B: + #endif + _SET_CS(2, val); break; #endif #ifdef TCCR3A - case TIMER3A: - case TIMER3B: - case TIMER3C: - _SET_CS(3, val); - break; + case TIMER3A: case TIMER3B: case TIMER3C: _SET_CS(3, val); break; #endif #ifdef TCCR4A - case TIMER4A: - case TIMER4B: - case TIMER4C: - _SET_CS(4, val); - break; + case TIMER4A: case TIMER4B: case TIMER4C: _SET_CS(4, val); break; #endif #ifdef TCCR5A - case TIMER5A: - case TIMER5B: - case TIMER5C: - _SET_CS(5, val); - break; + case TIMER5A: case TIMER5B: case TIMER5C: _SET_CS(5, val); break; #endif } } #endif // FAST_PWM_FAN -float calculate_volumetric_multiplier(const float diameter) { - if (!volumetric_enabled || diameter == 0) return 1.0; - return 1.0 / (M_PI * sq(diameter * 0.5)); -} - -void calculate_volumetric_multipliers() { - for (uint8_t i = 0; i < COUNT(filament_size); i++) - volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); -} - void enable_all_steppers() { enable_X(); enable_Y(); @@ -12981,102 +13825,185 @@ void disable_all_steppers() { disable_e_steppers(); } -#if ENABLED(HAVE_TMC2130) +#if ENABLED(MONITOR_DRIVER_STATUS) + /* + * Check for over temperature or short to ground error flags. + * Report and log warning of overtemperature condition. + * Reduce driver current in a persistent otpw condition. + * Keep track of otpw counter so we don't reduce current on a single instance, + * and so we don't repeatedly report warning before the condition is cleared. + */ - void automatic_current_control(TMC2130Stepper &st, String axisID) { - // Check otpw even if we don't use automatic control. Allows for flag inspection. - const bool is_otpw = st.checkOT(); + struct TMC_driver_data { + uint32_t drv_status; + bool is_otpw; + bool is_ot; + bool is_error; + }; + #if ENABLED(HAVE_TMC2130) + static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); } + static uint8_t get_status_response(TMC2130Stepper &st) { return st.status_response&0xF; } + static TMC_driver_data get_driver_data(TMC2130Stepper &st) { + constexpr uint32_t OTPW_bm = 0x4000000UL; + constexpr uint8_t OTPW_bp = 26; + constexpr uint32_t OT_bm = 0x2000000UL; + constexpr uint8_t OT_bp = 25; + constexpr uint8_t DRIVER_ERROR_bm = 0x2UL; + constexpr uint8_t DRIVER_ERROR_bp = 1; + TMC_driver_data data; + data.drv_status = st.DRV_STATUS(); + data.is_otpw = (data.drv_status & OTPW_bm)>>OTPW_bp; + data.is_ot = (data.drv_status & OT_bm)>>OT_bp; + data.is_error = (st.status_response & DRIVER_ERROR_bm)>>DRIVER_ERROR_bp; + return data; + } + #endif + #if ENABLED(HAVE_TMC2208) + static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); } + static uint8_t get_status_response(TMC2208Stepper &st) { + uint32_t drv_status = st.DRV_STATUS(); + uint8_t gstat = st.GSTAT(); + uint8_t response = 0; + response |= (drv_status >> (31-3)) & 0b1000; + response |= gstat & 0b11; + return response; + } + static TMC_driver_data get_driver_data(TMC2208Stepper &st) { + constexpr uint32_t OTPW_bm = 0b1ul; + constexpr uint8_t OTPW_bp = 0; + constexpr uint32_t OT_bm = 0b10ul; + constexpr uint8_t OT_bp = 1; + TMC_driver_data data; + data.drv_status = st.DRV_STATUS(); + data.is_otpw = (data.drv_status & OTPW_bm)>>OTPW_bp; + data.is_ot = (data.drv_status & OT_bm)>>OT_bp; + data.is_error = st.drv_err(); + return data; + } + #endif + + template + uint8_t monitor_tmc_driver(TMC &st, const char axisID, uint8_t otpw_cnt) { + TMC_driver_data data = get_driver_data(st); + + #if ENABLED(STOP_ON_ERROR) + if (data.is_error) { + SERIAL_EOL(); + SERIAL_ECHO(axisID); + SERIAL_ECHO(" driver error detected:"); + if (data.is_ot) SERIAL_ECHO("\novertemperature"); + if (st.s2ga()) SERIAL_ECHO("\nshort to ground (coil A)"); + if (st.s2gb()) SERIAL_ECHO("\nshort to ground (coil B)"); + SERIAL_EOL(); + #if ENABLED(TMC_DEBUG) + gcode_M122(); + #endif + kill(PSTR("Driver error")); + } + #endif // Report if a warning was triggered - static bool previous_otpw = false; - if (is_otpw && !previous_otpw) { + if (data.is_otpw && otpw_cnt==0) { char timestamp[10]; duration_t elapsed = print_job_timer.duration(); const bool has_days = (elapsed.value > 60*60*24L); (void)elapsed.toDigital(timestamp, has_days); + SERIAL_EOL(); SERIAL_ECHO(timestamp); SERIAL_ECHOPGM(": "); SERIAL_ECHO(axisID); - SERIAL_ECHOLNPGM(" driver overtemperature warning!"); + SERIAL_ECHOPGM(" driver overtemperature warning! ("); + SERIAL_ECHO(st.getCurrent()); + SERIAL_ECHOLN("mA)"); } - previous_otpw = is_otpw; - - #if CURRENT_STEP > 0 && ENABLED(AUTOMATIC_CURRENT_CONTROL) - // Return if user has not enabled current control start with M906 S1. - if (!auto_current_control) return; - - /** - * Decrease current if is_otpw is true. - * Bail out if driver is disabled. - * Increase current if OTPW has not been triggered yet. - */ - uint16_t current = st.getCurrent(); - if (is_otpw) { - st.setCurrent(current - CURRENT_STEP, R_SENSE, HOLD_MULTIPLIER); + #if CURRENT_STEP_DOWN > 0 + // Decrease current if is_otpw is true and driver is enabled and there's been more then 4 warnings + if (data.is_otpw && !st.isEnabled() && otpw_cnt > 4) { + st.setCurrent(st.getCurrent() - CURRENT_STEP_DOWN, R_SENSE, HOLD_MULTIPLIER); #if ENABLED(REPORT_CURRENT_CHANGE) SERIAL_ECHO(axisID); - SERIAL_ECHOPAIR(" current decreased to ", st.getCurrent()); + SERIAL_ECHOLNPAIR(" current decreased to ", st.getCurrent()); #endif } - - else if (!st.isEnabled()) - return; - - else if (!is_otpw && !st.getOTPW()) { - current += CURRENT_STEP; - if (current <= AUTO_ADJUST_MAX) { - st.setCurrent(current, R_SENSE, HOLD_MULTIPLIER); - #if ENABLED(REPORT_CURRENT_CHANGE) - SERIAL_ECHO(axisID); - SERIAL_ECHOPAIR(" current increased to ", st.getCurrent()); - #endif - } - } - SERIAL_EOL(); #endif + + if (data.is_otpw) { + otpw_cnt++; + st.flag_otpw = true; + } + else if (otpw_cnt>0) otpw_cnt--; + + if (report_tmc_status) { + const uint32_t pwm_scale = get_pwm_scale(st); + SERIAL_ECHO(axisID); + SERIAL_ECHOPAIR(":", pwm_scale); + SERIAL_ECHO(" |0b"); MYSERIAL.print(get_status_response(st), BIN); + SERIAL_ECHO("| "); + if (data.is_error) SERIAL_ECHO('E'); + else if (data.is_ot) SERIAL_ECHO('O'); + else if (data.is_otpw) SERIAL_ECHO('W'); + else if (otpw_cnt>0) MYSERIAL.print(otpw_cnt, DEC); + else if (st.flag_otpw) SERIAL_ECHO('F'); + SERIAL_ECHO("\t"); + } + + return otpw_cnt; } - void checkOverTemp() { + void monitor_tmc_driver() { static millis_t next_cOT = 0; if (ELAPSED(millis(), next_cOT)) { - next_cOT = millis() + 5000; - #if ENABLED(X_IS_TMC2130) - automatic_current_control(stepperX, "X"); + next_cOT = millis() + 500; + #if ENABLED(X_IS_TMC2130)|| (ENABLED(X_IS_TMC2208) && defined(X_HARDWARE_SERIAL)) || ENABLED(IS_TRAMS) + static uint8_t x_otpw_cnt = 0; + x_otpw_cnt = monitor_tmc_driver(stepperX, axis_codes[X_AXIS], x_otpw_cnt); #endif - #if ENABLED(Y_IS_TMC2130) - automatic_current_control(stepperY, "Y"); + #if ENABLED(Y_IS_TMC2130)|| (ENABLED(Y_IS_TMC2208) && defined(Y_HARDWARE_SERIAL)) || ENABLED(IS_TRAMS) + static uint8_t y_otpw_cnt = 0; + y_otpw_cnt = monitor_tmc_driver(stepperY, axis_codes[Y_AXIS], y_otpw_cnt); #endif - #if ENABLED(Z_IS_TMC2130) - automatic_current_control(stepperZ, "Z"); + #if ENABLED(Z_IS_TMC2130)|| (ENABLED(Z_IS_TMC2208) && defined(Z_HARDWARE_SERIAL)) || ENABLED(IS_TRAMS) + static uint8_t z_otpw_cnt = 0; + z_otpw_cnt = monitor_tmc_driver(stepperZ, axis_codes[Z_AXIS], z_otpw_cnt); #endif - #if ENABLED(X2_IS_TMC2130) - automatic_current_control(stepperX2, "X2"); + #if ENABLED(X2_IS_TMC2130) || (ENABLED(X2_IS_TMC2208) && defined(X2_HARDWARE_SERIAL)) + static uint8_t x2_otpw_cnt = 0; + x2_otpw_cnt = monitor_tmc_driver(stepperX2, axis_codes[X_AXIS], x2_otpw_cnt); #endif - #if ENABLED(Y2_IS_TMC2130) - automatic_current_control(stepperY2, "Y2"); + #if ENABLED(Y2_IS_TMC2130) || (ENABLED(Y2_IS_TMC2208) && defined(Y2_HARDWARE_SERIAL)) + static uint8_t y2_otpw_cnt = 0; + y2_otpw_cnt = monitor_tmc_driver(stepperY2, axis_codes[Y_AXIS], y2_otpw_cnt); #endif - #if ENABLED(Z2_IS_TMC2130) - automatic_current_control(stepperZ2, "Z2"); + #if ENABLED(Z2_IS_TMC2130) || (ENABLED(Z2_IS_TMC2208) && defined(Z2_HARDWARE_SERIAL)) + static uint8_t z2_otpw_cnt = 0; + z2_otpw_cnt = monitor_tmc_driver(stepperZ2, axis_codes[Z_AXIS], z2_otpw_cnt); #endif - #if ENABLED(E0_IS_TMC2130) - automatic_current_control(stepperE0, "E0"); + #if ENABLED(E0_IS_TMC2130)|| (ENABLED(E0_IS_TMC2208) && defined(E0_HARDWARE_SERIAL)) || ENABLED(IS_TRAMS) + static uint8_t e0_otpw_cnt = 0; + e0_otpw_cnt = monitor_tmc_driver(stepperE0, axis_codes[E_AXIS], e0_otpw_cnt); #endif - #if ENABLED(E1_IS_TMC2130) - automatic_current_control(stepperE1, "E1"); + #if ENABLED(E1_IS_TMC2130) || (ENABLED(E1_IS_TMC2208) && defined(E1_HARDWARE_SERIAL)) + static uint8_t e1_otpw_cnt = 0; + e1_otpw_cnt = monitor_tmc_driver(stepperE1, axis_codes[E_AXIS], e1_otpw_cnt); #endif - #if ENABLED(E2_IS_TMC2130) - automatic_current_control(stepperE2, "E2"); + #if ENABLED(E2_IS_TMC2130) || (ENABLED(E2_IS_TMC2208) && defined(E2_HARDWARE_SERIAL)) + static uint8_t e2_otpw_cnt = 0; + e2_otpw_cnt = monitor_tmc_driver(stepperE2, axis_codes[E_AXIS], e2_otpw_cnt); #endif - #if ENABLED(E3_IS_TMC2130) - automatic_current_control(stepperE3, "E3"); + #if ENABLED(E3_IS_TMC2130) || (ENABLED(E3_IS_TMC2208) && defined(E3_HARDWARE_SERIAL)) + static uint8_t e3_otpw_cnt = 0; + e3_otpw_cnt = monitor_tmc_driver(stepperE3, axis_codes[E_AXIS], e3_otpw_cnt); #endif - #if ENABLED(E4_IS_TMC2130) - automatic_current_control(stepperE4, "E4"); + #if ENABLED(E4_IS_TMC2130) || (ENABLED(E4_IS_TMC2208) && defined(E4_HARDWARE_SERIAL)) + static uint8_t e4_otpw_cnt = 0; + e4_otpw_cnt = monitor_tmc_driver(stepperE4, axis_codes[E_AXIS], e4_otpw_cnt); #endif + + if (report_tmc_status) SERIAL_EOL(); } } -#endif // HAVE_TMC2130 +#endif // MONITOR_DRIVER_STATUS /** * Manage several activities: @@ -13129,7 +14056,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { disable_e_steppers(); #endif #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD) // Only needed with an LCD - ubl_lcd_map_control = defer_return_to_status = false; + ubl.lcd_map_control = defer_return_to_status = false; #endif } @@ -13243,7 +14170,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) { // travel moves have been received so enact them delayed_move_time = 0xFFFFFFFFUL; // force moves to be done - set_destination_to_current(); + set_destination_from_current(); prepare_move_to_destination(); } #endif @@ -13252,8 +14179,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { handle_status_leds(); #endif - #if ENABLED(HAVE_TMC2130) - checkOverTemp(); + #if ENABLED(MONITOR_DRIVER_STATUS) + monitor_tmc_driver(); #endif planner.check_axes_activity(); @@ -13276,7 +14203,7 @@ void idle( host_keepalive(); #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) - auto_report_temperatures(); + thermalManager.auto_report_temperatures(); #endif manage_inactivity( @@ -13390,7 +14317,7 @@ void setup() { Max7219_init(); #endif - #ifdef DISABLE_JTAG + #if ENABLED(DISABLE_JTAG) // Disable JTAG on AT90USB chips to free up pins for IO MCUCR = 0x80; MCUCR = 0x80; @@ -13412,6 +14339,10 @@ void setup() { SERIAL_PROTOCOLLNPGM("start"); SERIAL_ECHO_START(); + #if ENABLED(HAVE_TMC2208) + tmc2208_serial_begin(); + #endif + // Check startup - does nothing if bootloader sets MCUSR to 0 byte mcu = MCUSR; if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP); @@ -13522,9 +14453,8 @@ void setup() { OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // turn it off #endif - #if ENABLED(NEOPIXEL_LED) - SET_OUTPUT(NEOPIXEL_PIN); - setup_neopixel(); + #if HAS_COLOR_LEDS + leds.setup(); #endif #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) @@ -13548,32 +14478,26 @@ void setup() { lcd_init(); - #ifndef CUSTOM_BOOTSCREEN_TIMEOUT - #define CUSTOM_BOOTSCREEN_TIMEOUT 2500 - #endif - #if ENABLED(SHOW_BOOTSCREEN) - #if ENABLED(DOGLCD) // On DOGM the first bootscreen is already drawn - #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) - safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT); // Custom boot screen pause - lcd_bootscreen(); // Show Marlin boot screen - #endif - safe_delay(BOOTSCREEN_TIMEOUT); // Pause - #elif ENABLED(ULTRA_LCD) - lcd_bootscreen(); - #if DISABLED(SDSUPPORT) - lcd_init(); - #endif - #endif + lcd_bootscreen(); #endif #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 - // Initialize mixing to 100% color 1 - for (uint8_t i = 0; i < MIXING_STEPPERS; i++) - mixing_factor[i] = (i == 0) ? 1.0 : 0.0; - for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++) + // Virtual Tools 0, 1, 2, 3 = Filament 1, 2, 3, 4, etc. + for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS && t < MIXING_STEPPERS; t++) for (uint8_t i = 0; i < MIXING_STEPPERS; i++) - mixing_virtual_tool_mix[t][i] = mixing_factor[i]; + mixing_virtual_tool_mix[t][i] = (t == i) ? 1.0 : 0.0; + + // Remaining virtual tools are 100% filament 1 + #if MIXING_STEPPERS < MIXING_VIRTUAL_TOOLS + for (uint8_t t = MIXING_STEPPERS; t < MIXING_VIRTUAL_TOOLS; t++) + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_virtual_tool_mix[t][i] = (i == 0) ? 1.0 : 0.0; + #endif + + // Initialize mixing to tool 0 color + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_factor[i] = mixing_virtual_tool_mix[0][i]; #endif #if ENABLED(BLTOUCH) @@ -13613,7 +14537,7 @@ void setup() { pe_deactivate_magnet(1); #endif #endif - #if ENABLED(MKS_12864OLED) + #if ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306) SET_OUTPUT(LCD_PINS_DC); OUT_WRITE(LCD_PINS_RS, LOW); delay(1000); @@ -13686,4 +14610,3 @@ void loop() { endstops.report_state(); idle(); } - diff --git a/Marlin/Max7219_Debug_LEDs.cpp b/Marlin/Max7219_Debug_LEDs.cpp index d6110053f3..b38a75dbf6 100644 --- a/Marlin/Max7219_Debug_LEDs.cpp +++ b/Marlin/Max7219_Debug_LEDs.cpp @@ -39,12 +39,14 @@ * void Max7219_init(); * void Max7219_PutByte(uint8_t data); * void Max7219(uint8_t reg, uint8_t data); - * void Max7219_LED_On(uint8_t row, uint8_t col); - * void Max7219_LED_Off(uint8_t row, uint8_t col); - * void Max7219_LED_Toggle(uint8_t row, uint8_t col); + * void Max7219_LED_On(uint8_t col, uint8_t row); + * void Max7219_LED_Off(uint8_t col, uint8_t row); + * void Max7219_LED_Toggle(uint8_t col, uint8_t row); * void Max7219_Clear_Row(uint8_t row); * void Max7219_Clear_Column(uint8_t col); * void Max7219_Set_Row(uint8_t row, uint8_t val); + * void Max7219_Set_2_Rows(uint8_t row, uint16_t val); + * void Max7219_Set_4_Rows(uint8_t row, uint32_t val); * void Max7219_Set_Column(uint8_t col, uint8_t val); * void Max7219_idle_tasks(); */ @@ -53,184 +55,295 @@ #if ENABLED(MAX7219_DEBUG) - #include "Marlin.h" - #include "planner.h" - #include "stepper.h" - #include "Max7219_Debug_LEDs.h" +#include "Max7219_Debug_LEDs.h" - static uint8_t LEDs[8] = { 0 }; +#include "planner.h" +#include "stepper.h" +#include "Marlin.h" - void Max7219_PutByte(uint8_t data) { - for (uint8_t i = 8; i--;) { - WRITE(MAX7219_CLK_PIN, LOW); // tick - WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit - WRITE(MAX7219_CLK_PIN, HIGH); // tock - data <<= 1; - } +static uint8_t LEDs[8] = { 0 }; + +#ifdef CPU_32_BIT + #define MS_DELAY() delayMicroseconds(5) // 32-bit processors need a delay to stabilize the signal +#else + #define MS_DELAY() NOOP +#endif + +void Max7219_PutByte(uint8_t data) { + CRITICAL_SECTION_START + for (uint8_t i = 8; i--;) { + MS_DELAY(); + WRITE(MAX7219_CLK_PIN, LOW); // tick + MS_DELAY(); + WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit + MS_DELAY(); + WRITE(MAX7219_CLK_PIN, HIGH); // tock + MS_DELAY(); + data <<= 1; } + CRITICAL_SECTION_END +} - void Max7219(const uint8_t reg, const uint8_t data) { - WRITE(MAX7219_LOAD_PIN, LOW); // begin - Max7219_PutByte(reg); // specify register - Max7219_PutByte(data); // put data - WRITE(MAX7219_LOAD_PIN, LOW); // and tell the chip to load the data - WRITE(MAX7219_LOAD_PIN, HIGH); +void Max7219(const uint8_t reg, const uint8_t data) { + MS_DELAY(); + CRITICAL_SECTION_START + WRITE(MAX7219_LOAD_PIN, LOW); // begin + MS_DELAY(); + Max7219_PutByte(reg); // specify register + MS_DELAY(); + Max7219_PutByte(data); // put data + MS_DELAY(); + WRITE(MAX7219_LOAD_PIN, LOW); // and tell the chip to load the data + MS_DELAY(); + WRITE(MAX7219_LOAD_PIN, HIGH); + CRITICAL_SECTION_END + MS_DELAY(); +} + +void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on) { + if (row > 7 || col > 7) { + SERIAL_ECHOPAIR("??? Max7219_LED_Set(", (int)row); + SERIAL_ECHOPAIR(",", (int)col); + SERIAL_ECHOLNPGM(")"); + return; } + if (TEST(LEDs[row], col) == on) return; // if LED is already on/off, leave alone + if (on) SBI(LEDs[row], col); else CBI(LEDs[row], col); + Max7219(8 - row, LEDs[row]); +} - void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on) { - if (row > 7 || col > 7) return; - if (TEST(LEDs[row], col) == on) return; // if LED is already on/off, leave alone - if (on) SBI(LEDs[row], col); else CBI(LEDs[row], col); - Max7219(8 - row, LEDs[row]); +void Max7219_LED_On(const uint8_t col, const uint8_t row) { + if (row > 7 || col > 7) { + SERIAL_ECHOPAIR("??? Max7219_LED_On(", (int)col); + SERIAL_ECHOPAIR(",", (int)row); + SERIAL_ECHOLNPGM(")"); + return; } + Max7219_LED_Set(col, row, true); +} - void Max7219_LED_On(const uint8_t row, const uint8_t col) { - Max7219_LED_Set(row, col, true); +void Max7219_LED_Off(const uint8_t col, const uint8_t row) { + if (row > 7 || col > 7) { + SERIAL_ECHOPAIR("??? Max7219_LED_Off(", (int)row); + SERIAL_ECHOPAIR(",", (int)col); + SERIAL_ECHOLNPGM(")"); + return; } + Max7219_LED_Set(col, row, false); +} - void Max7219_LED_Off(const uint8_t row, const uint8_t col) { - Max7219_LED_Set(row, col, false); +void Max7219_LED_Toggle(const uint8_t col, const uint8_t row) { + if (row > 7 || col > 7) { + SERIAL_ECHOPAIR("??? Max7219_LED_Toggle(", (int)row); + SERIAL_ECHOPAIR(",", (int)col); + SERIAL_ECHOLNPGM(")"); + return; } + if (TEST(LEDs[row], col)) + Max7219_LED_Off(col, row); + else + Max7219_LED_On(col, row); +} - void Max7219_LED_Toggle(const uint8_t row, const uint8_t col) { - if (row > 7 || col > 7) return; - if (TEST(LEDs[row], col)) - Max7219_LED_Off(row, col); +void Max7219_Clear_Column(const uint8_t col) { + if (col > 7) { + SERIAL_ECHOPAIR("??? Max7219_Clear_Column(", (int)col); + SERIAL_ECHOLNPGM(")"); + return; + } + LEDs[col] = 0; + Max7219(8 - col, LEDs[col]); +} + +void Max7219_Clear_Row(const uint8_t row) { + if (row > 7) { + SERIAL_ECHOPAIR("??? Max7219_Clear_Row(", (int)row); + SERIAL_ECHOLNPGM(")"); + return; + } + for (uint8_t c = 0; c <= 7; c++) + Max7219_LED_Off(c, row); +} + +void Max7219_Set_Row(const uint8_t row, const uint8_t val) { + if (row > 7) { + SERIAL_ECHOPAIR("??? Max7219_Set_Row(", (int)row); + SERIAL_ECHOPAIR(",", (int)val); + SERIAL_ECHOLNPGM(")"); + return; + } + for (uint8_t b = 0; b <= 7; b++) + if (TEST(val, b)) + Max7219_LED_On(7 - b, row); else - Max7219_LED_On(row, col); + Max7219_LED_Off(7 - b, row); +} + +void Max7219_Set_2_Rows(const uint8_t row, const uint16_t val) { + if (row > 6) { + SERIAL_ECHOPAIR("??? Max7219_Set_2_Rows(", (int)row); + SERIAL_ECHOPAIR(",", (int)val); + SERIAL_ECHOLNPGM(")"); + return; + } + Max7219_Set_Row(row + 1, (val >> 8) & 0xFF); + Max7219_Set_Row(row + 0, (val ) & 0xFF); +} + +void Max7219_Set_4_Rows(const uint8_t row, const uint32_t val) { + if (row > 4) { + SERIAL_ECHOPAIR("??? Max7219_Set_4_Rows(", (int)row); + SERIAL_ECHOPAIR(",", (long)val); + SERIAL_ECHOLNPGM(")"); + return; + } + Max7219_Set_Row(row + 3, (val >> 24) & 0xFF); + Max7219_Set_Row(row + 2, (val >> 16) & 0xFF); + Max7219_Set_Row(row + 1, (val >> 8) & 0xFF); + Max7219_Set_Row(row + 0, (val ) & 0xFF); +} + +void Max7219_Set_Column(const uint8_t col, const uint8_t val) { + if (col > 7) { + SERIAL_ECHOPAIR("??? Max7219_Column(", (int)col); + SERIAL_ECHOPAIR(",", (int)val); + SERIAL_ECHOLNPGM(")"); + return; + } + LEDs[col] = val; + Max7219(8 - col, LEDs[col]); +} + +void Max7219_init() { + uint8_t i, x, y; + + SET_OUTPUT(MAX7219_DIN_PIN); + SET_OUTPUT(MAX7219_CLK_PIN); + + OUT_WRITE(MAX7219_LOAD_PIN, HIGH); + delay(1); + + //initiation of the max 7219 + Max7219(max7219_reg_scanLimit, 0x07); + Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits) + Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode + Max7219(max7219_reg_displayTest, 0x00); // no display test + Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set + // range: 0x00 to 0x0F + for (i = 0; i <= 7; i++) { // empty registers, turn all LEDs off + LEDs[i] = 0x00; + Max7219(i + 1, 0); } - void Max7219_Clear_Column(const uint8_t col) { - if (col > 7) return; - LEDs[col] = 0; - Max7219(8 - col, LEDs[col]); - } - - void Max7219_Clear_Row(const uint8_t row) { - if (row > 7) return; - for (uint8_t c = 0; c <= 7; c++) - Max7219_LED_Off(c, row); - } - - void Max7219_Set_Row(const uint8_t row, const uint8_t val) { - if (row > 7) return; - for (uint8_t b = 0; b <= 7; b++) - if (TEST(val, b)) - Max7219_LED_On(7 - b, row); - else - Max7219_LED_Off(7 - b, row); - } - - void Max7219_Set_Column(const uint8_t col, const uint8_t val) { - if (col > 7) return; - LEDs[col] = val; - Max7219(8 - col, LEDs[col]); - } - - void Max7219_init() { - uint8_t i, x, y; - - SET_OUTPUT(MAX7219_DIN_PIN); - SET_OUTPUT(MAX7219_CLK_PIN); - - OUT_WRITE(MAX7219_LOAD_PIN, HIGH); - - //initiation of the max 7219 - Max7219(max7219_reg_scanLimit, 0x07); - Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits) - Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode - Max7219(max7219_reg_displayTest, 0x00); // no display test - Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set - // range: 0x00 to 0x0F - for (i = 0; i <= 7; i++) { // empty registers, turn all LEDs off - LEDs[i] = 0x00; - Max7219(i + 1, 0); + for (x = 0; x <= 7; x++) // Do an aesthetically pleasing pattern to fully test + for (y = 0; y <= 7; y++) { // the Max7219 module and LEDs. First, turn them + Max7219_LED_On(x, y); // all on. + delay(3); } - for (x = 0; x <= 7; x++) // Do an aesthetically pleasing pattern to fully test - for (y = 0; y <= 7; y++) { // the Max7219 module and LEDs. First, turn them - Max7219_LED_On(x, y); // all on. - delay(3); - } + for (x = 0; x <= 7; x++) // Now, turn them all off. + for (y = 0; y <= 7; y++) { + Max7219_LED_Off(x, y); + delay(3); // delay() is OK here. Max7219_init() is only called from + } // setup() and nothing is running yet. - for (x = 0; x <= 7; x++) // Now, turn them all off. - for (y = 0; y <= 7; y++) { - Max7219_LED_Off(x, y); - delay(3); // delay() is OK here. Max7219_init() is only called from - } // setup() and nothing is running yet. + delay(150); - delay(150); + for (x = 8; x--;) // Now, do the same thing from the opposite direction + for (y = 0; y <= 7; y++) { + Max7219_LED_On(x, y); + delay(2); + } - for (x = 8; x--;) // Now, do the same thing from the opposite direction - for (y = 0; y <= 7; y++) { - Max7219_LED_On(x, y); - delay(2); - } - - for (x = 8; x--;) - for (y = 0; y <= 7; y++) { - Max7219_LED_Off(x, y); - delay(2); - } - } + for (x = 8; x--;) + for (y = 0; y <= 7; y++) { + Max7219_LED_Off(x, y); + delay(2); + } +} /** - * These are sample debug features to demonstrate the usage of the 8x8 LED Matrix for debug purposes. - * There is very little CPU burden added to the system by displaying information within the idle() - * task. - * - * But with that said, if your debugging can be facilitated by making calls into the library from - * other places in the code, feel free to do it. The CPU burden for a few calls to toggle an LED - * or clear a row is not very significant. - */ - void Max7219_idle_tasks() { - #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) - static int debug_cnt = 0; - if (debug_cnt++ > 100) { - Max7219_LED_Toggle(7, 7); - debug_cnt = 0; - } - #endif +* These are sample debug features to demonstrate the usage of the 8x8 LED Matrix for debug purposes. +* There is very little CPU burden added to the system by displaying information within the idle() +* task. +* +* But with that said, if your debugging can be facilitated by making calls into the library from +* other places in the code, feel free to do it. The CPU burden for a few calls to toggle an LED +* or clear a row is not very significant. +*/ +void Max7219_idle_tasks() { +#if MAX7219_DEBUG_STEPPER_HEAD || MAX7219_DEBUG_STEPPER_TAIL || MAX7219_DEBUG_STEPPER_QUEUE + CRITICAL_SECTION_START + #if MAX7219_DEBUG_STEPPER_HEAD || MAX7219_DEBUG_STEPPER_QUEUE + const uint8_t head = planner.block_buffer_head; + #endif + #if MAX7219_DEBUG_STEPPER_TAIL || MAX7219_DEBUG_STEPPER_QUEUE + const uint8_t tail = planner.block_buffer_tail; + #endif + CRITICAL_SECTION_END +#endif - #ifdef MAX7219_DEBUG_STEPPER_HEAD - Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_HEAD); - Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_HEAD + 1); - if ( planner.block_buffer_head < 8) - Max7219_LED_On( planner.block_buffer_head, MAX7219_DEBUG_STEPPER_HEAD); + #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) + static millis_t next_blink = 0; + if (ELAPSED(millis(), next_blink)) { + Max7219_LED_Toggle(7, 7); + next_blink = millis() + 750; + } + #endif + + #ifdef MAX7219_DEBUG_STEPPER_HEAD + static int16_t last_head_cnt = 0; + if (last_head_cnt != head) { + if (last_head_cnt < 8) + Max7219_LED_Off(last_head_cnt, MAX7219_DEBUG_STEPPER_HEAD); else - Max7219_LED_On( planner.block_buffer_head-8, MAX7219_DEBUG_STEPPER_HEAD+1); - #endif + Max7219_LED_Off(last_head_cnt - 8, MAX7219_DEBUG_STEPPER_HEAD + 1); - #ifdef MAX7219_DEBUG_STEPPER_TAIL - Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_TAIL); - Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_TAIL + 1); - if ( planner.block_buffer_tail < 8) - Max7219_LED_On( planner.block_buffer_tail, MAX7219_DEBUG_STEPPER_TAIL ); + last_head_cnt = head; + if (head < 8) + Max7219_LED_On(head, MAX7219_DEBUG_STEPPER_HEAD); else - Max7219_LED_On( planner.block_buffer_tail-8, MAX7219_DEBUG_STEPPER_TAIL+1 ); - #endif + Max7219_LED_On(head - 8, MAX7219_DEBUG_STEPPER_HEAD + 1); + } + #endif - #ifdef MAX7219_DEBUG_STEPPER_QUEUE - static int16_t last_depth = 0; - int16_t current_depth = planner.block_buffer_head - planner.block_buffer_tail; - if (current_depth != last_depth) { // usually, no update will be needed. - if (current_depth < 0) current_depth += BLOCK_BUFFER_SIZE; - NOMORE(current_depth, BLOCK_BUFFER_SIZE); - NOMORE(current_depth, 16); // if the BLOCK_BUFFER_SIZE is greater than 16, two lines - // of LEDs is enough to see if the buffer is draining + #ifdef MAX7219_DEBUG_STEPPER_TAIL + static int16_t last_tail_cnt = 0; + if (last_tail_cnt != tail) { + if (last_tail_cnt < 8) + Max7219_LED_Off(last_tail_cnt, MAX7219_DEBUG_STEPPER_TAIL); + else + Max7219_LED_Off(last_tail_cnt - 8, MAX7219_DEBUG_STEPPER_TAIL + 1); - const uint8_t st = min(current_depth, last_depth), - en = max(current_depth, last_depth); - if (current_depth < last_depth) - for (uint8_t i = st; i <= en; i++) // clear the highest order LEDs - Max7219_LED_Off(i >> 1, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); - else - for (uint8_t i = st; i <= en; i++) // set the highest order LEDs - Max7219_LED_On(i >> 1, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); + last_tail_cnt = tail; + if (tail < 8) + Max7219_LED_On(tail, MAX7219_DEBUG_STEPPER_TAIL); + else + Max7219_LED_On(tail - 8, MAX7219_DEBUG_STEPPER_TAIL + 1); + } + #endif - last_depth = current_depth; - } - #endif - } + #ifdef MAX7219_DEBUG_STEPPER_QUEUE + static int16_t last_depth = 0; + int16_t current_depth = head - tail; + if (current_depth != last_depth) { // usually, no update will be needed. + if (current_depth < 0) current_depth += BLOCK_BUFFER_SIZE; + NOMORE(current_depth, BLOCK_BUFFER_SIZE); + NOMORE(current_depth, 16); // if the BLOCK_BUFFER_SIZE is greater than 16, two lines + // of LEDs is enough to see if the buffer is draining + + const uint8_t st = min(current_depth, last_depth), + en = max(current_depth, last_depth); + if (current_depth < last_depth) + for (uint8_t i = st; i <= en; i++) // clear the highest order LEDs + Max7219_LED_Off(i / 2, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); + else + for (uint8_t i = st; i <= en; i++) // set the LEDs to current depth + Max7219_LED_On(i / 2, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); + + last_depth = current_depth; + } + #endif +} #endif // MAX7219_DEBUG diff --git a/Marlin/Max7219_Debug_LEDs.h b/Marlin/Max7219_Debug_LEDs.h index 71a5124e39..3beccb0ea8 100644 --- a/Marlin/Max7219_Debug_LEDs.h +++ b/Marlin/Max7219_Debug_LEDs.h @@ -40,12 +40,14 @@ * void Max7219_PutByte(uint8_t data); * void Max7219(uint8_t reg, uint8_t data); * void Max7219_LED_Set(uint8_t row, uint8_t col, bool on); - * void Max7219_LED_On(uint8_t row, uint8_t col); - * void Max7219_LED_Off(uint8_t row, uint8_t col); + * void Max7219_LED_On(uint8_t col, uint8_t row); + * void Max7219_LED_Off(uint8_t col, uint8_t row); * void Max7219_LED_Toggle(uint8_t row, uint8_t col); * void Max7219_Clear_Row(uint8_t row); * void Max7219_Clear_Column(uint8_t col); * void Max7219_Set_Row(uint8_t row, uint8_t val); + * void Max7219_Set_2_Rows(uint8_t row, uint16_t val); + * void Max7219_Set_4_Rows(uint8_t row, uint32_t val); * void Max7219_Set_Column(uint8_t col, uint8_t val); * void Max7219_idle_tasks(); */ @@ -53,36 +55,36 @@ #ifndef __MAX7219_DEBUG_LEDS_H__ #define __MAX7219_DEBUG_LEDS_H__ - // - // define max7219 registers - // - #define max7219_reg_noop 0x00 - #define max7219_reg_digit0 0x01 - #define max7219_reg_digit1 0x02 - #define max7219_reg_digit2 0x03 - #define max7219_reg_digit3 0x04 - #define max7219_reg_digit4 0x05 - #define max7219_reg_digit5 0x06 - #define max7219_reg_digit6 0x07 - #define max7219_reg_digit7 0x08 +// +// define max7219 registers +// +#define max7219_reg_noop 0x00 +#define max7219_reg_digit0 0x01 +#define max7219_reg_digit1 0x02 +#define max7219_reg_digit2 0x03 +#define max7219_reg_digit3 0x04 +#define max7219_reg_digit4 0x05 +#define max7219_reg_digit5 0x06 +#define max7219_reg_digit6 0x07 +#define max7219_reg_digit7 0x08 - #define max7219_reg_intensity 0x0A - #define max7219_reg_displayTest 0x0F - #define max7219_reg_decodeMode 0x09 - #define max7219_reg_scanLimit 0x0B - #define max7219_reg_shutdown 0x0C +#define max7219_reg_intensity 0x0A +#define max7219_reg_displayTest 0x0F +#define max7219_reg_decodeMode 0x09 +#define max7219_reg_scanLimit 0x0B +#define max7219_reg_shutdown 0x0C - void Max7219_init(); - void Max7219_PutByte(uint8_t data); - void Max7219(const uint8_t reg, const uint8_t data); - void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on); - void Max7219_LED_On(const uint8_t row, const uint8_t col); - void Max7219_LED_Off(const uint8_t row, const uint8_t col); - void Max7219_LED_Toggle(const uint8_t row, const uint8_t col); - void Max7219_Clear_Row(const uint8_t row); - void Max7219_Clear_Column(const uint8_t col); - void Max7219_Set_Row(const uint8_t row, const uint8_t val); - void Max7219_Set_Column(const uint8_t col, const uint8_t val); - void Max7219_idle_tasks(); +void Max7219_init(); +void Max7219_PutByte(uint8_t data); +void Max7219(const uint8_t reg, const uint8_t data); +void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on); +void Max7219_LED_On(const uint8_t row, const uint8_t col); +void Max7219_LED_Off(const uint8_t row, const uint8_t col); +void Max7219_LED_Toggle(const uint8_t row, const uint8_t col); +void Max7219_Clear_Row(const uint8_t row); +void Max7219_Clear_Column(const uint8_t col); +void Max7219_Set_Row(const uint8_t row, const uint8_t val); +void Max7219_Set_Column(const uint8_t col, const uint8_t val); +void Max7219_idle_tasks(); #endif // __MAX7219_DEBUG_LEDS_H__ diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index 7d960f860c..f3749c6cb4 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -26,6 +26,9 @@ * Test configuration values for errors at compile-time. */ +#ifndef _SANITYCHECK_H_ +#define _SANITYCHECK_H_ + /** * Require gcc 4.7 or newer (first included with Arduino 1.6.8) for C++11 features. */ @@ -78,8 +81,6 @@ #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead." #elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS) #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead." -#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP) - #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2." #elif defined(LANGUAGE_INCLUDE) #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration." #elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y) @@ -182,10 +183,12 @@ #error "MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration." #elif defined(UBL_MESH_NUM_X_POINTS) || defined(UBL_MESH_NUM_Y_POINTS) #error "UBL_MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration." +#elif defined(UBL_G26_MESH_VALIDATION) + #error "UBL_G26_MESH_VALIDATION is now G26_MESH_VALIDATION. Please update your configuration." #elif defined(UBL_MESH_EDIT_ENABLED) - #error "UBL_MESH_EDIT_ENABLED is now UBL_G26_MESH_VALIDATION. Please update your configuration." + #error "UBL_MESH_EDIT_ENABLED is now G26_MESH_VALIDATION. Please update your configuration." #elif defined(UBL_MESH_EDITING) - #error "UBL_MESH_EDITING is now UBL_G26_MESH_VALIDATION. Please update your configuration." + #error "UBL_MESH_EDITING is now G26_MESH_VALIDATION. Please update your configuration." #elif defined(BLTOUCH_HEATERS_OFF) #error "BLTOUCH_HEATERS_OFF is now PROBING_HEATERS_OFF. Please update your configuration." #elif defined(BEEPER) @@ -212,6 +215,24 @@ #error "ADVANCE was removed in Marlin 1.1.6. Please use LIN_ADVANCE." #elif defined(NEOPIXEL_RGBW_LED) #error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration." +#elif defined(UBL_MESH_INSET) + #error "UBL_MESH_INSET is now just MESH_INSET. Please update your configuration." +#elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y) + #error "UBL_MESH_(MIN|MAX)_[XY] is now just MESH_(MIN|MAX)_[XY]. Please update your configuration." +#elif defined(ENABLE_MESH_EDIT_GFX_OVERLAY) + #error "ENABLE_MESH_EDIT_GFX_OVERLAY is now MESH_EDIT_GFX_OVERLAY. Please update your configuration." +#elif defined(BABYSTEP_ZPROBE_GFX_REVERSE) + #error "BABYSTEP_ZPROBE_GFX_REVERSE is now set by OVERLAY_GFX_REVERSE. Please update your configurations." +#elif defined(UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN) + #error "UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN is now SEGMENT_LEVELED_MOVES. Please update your configuration." +#elif HAS_PID_HEATING && (defined(K1) || !defined(PID_K1)) + #error "K1 is now PID_K1. Please update your configuration." +#elif defined(PROBE_DOUBLE_TOUCH) + #error "PROBE_DOUBLE_TOUCH is now MULTIPLE_PROBING. Please update your configuration." +#elif defined(ANET_KEYPAD_LCD) + #error "ANET_KEYPAD_LCD is now ZONESTAR_LCD. Please update your configuration." +#elif defined(MEASURED_LOWER_LIMIT) || defined(MEASURED_UPPER_LIMIT) + #error "MEASURED_(UPPER|LOWER)_LIMIT is now FILWIDTH_ERROR_MARGIN. Please update your configuration." #endif /** @@ -235,6 +256,21 @@ #error "WEBSITE_URL must be specified." #endif +/** + * Serial + */ +#ifndef USBCON + #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 + #error "SERIAL_XON_XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." + #elif RX_BUFFER_SIZE && (RX_BUFFER_SIZE < 2 || !IS_POWER_OF_2(RX_BUFFER_SIZE)) + #error "RX_BUFFER_SIZE must be a power of 2 greater than 1." + #elif TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE)) + #error "TX_BUFFER_SIZE must be 0, a power of 2 greater than 1, and no greater than 256." + #endif +#elif ENABLED(SERIAL_XON_XOFF) + #error "SERIAL_XON_XOFF is not supported on USB-native AVR devices." +#endif + /** * Dual Stepper Drivers */ @@ -254,17 +290,40 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds ([XY]_MIN_POS, [XY]_MAX_POS) are too narrow to contain [XY]_BED_SIZE."); +/** + * Granular software endstops (Marlin >= 1.1.7) + */ +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) && DISABLED(MIN_SOFTWARE_ENDSTOP_Z) + #if IS_KINEMATIC + #error "MIN_SOFTWARE_ENDSTOPS on DELTA/SCARA also requires MIN_SOFTWARE_ENDSTOP_Z." + #elif DISABLED(MIN_SOFTWARE_ENDSTOP_X) && DISABLED(MIN_SOFTWARE_ENDSTOP_Y) + #error "MIN_SOFTWARE_ENDSTOPS requires at least one of the MIN_SOFTWARE_ENDSTOP_[XYZ] options." + #endif +#endif + +#if ENABLED(MAX_SOFTWARE_ENDSTOPS) && DISABLED(MAX_SOFTWARE_ENDSTOP_Z) + #if IS_KINEMATIC + #error "MAX_SOFTWARE_ENDSTOPS on DELTA/SCARA also requires MAX_SOFTWARE_ENDSTOP_Z." + #elif DISABLED(MAX_SOFTWARE_ENDSTOP_X) && DISABLED(MAX_SOFTWARE_ENDSTOP_Y) + #error "MAX_SOFTWARE_ENDSTOPS requires at least one of the MAX_SOFTWARE_ENDSTOP_[XYZ] options." + #endif +#endif + /** * Progress Bar */ #if ENABLED(LCD_PROGRESS_BAR) #if DISABLED(SDSUPPORT) #error "LCD_PROGRESS_BAR requires SDSUPPORT." + #elif DISABLED(ULTRA_LCD) + #error "LCD_PROGRESS_BAR requires a character LCD." #elif ENABLED(DOGLCD) #error "LCD_PROGRESS_BAR does not apply to graphical displays." #elif ENABLED(FILAMENT_LCD_DISPLAY) #error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both." #endif +#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && DISABLED(DOGLCD) + #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR or Graphical LCD." #endif /** @@ -282,6 +341,16 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)." #endif #endif + + #if ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM) + #if SDSORT_CACHE_VFATS < 2 + #error "SDSORT_CACHE_VFATS must be 2 or greater!" + #elif SDSORT_CACHE_VFATS > MAX_VFAT_ENTRIES + #undef SDSORT_CACHE_VFATS + #define SDSORT_CACHE_VFATS MAX_VFAT_ENTRIES + #warning "SDSORT_CACHE_VFATS was reduced to MAX_VFAT_ENTRIES!" + #endif + #endif #endif /** @@ -299,9 +368,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, * Babystepping */ #if ENABLED(BABYSTEPPING) - #if DISABLED(ULTRA_LCD) && DISABLED(I2C_POSITION_ENCODERS) - #error "BABYSTEPPING requires an LCD controller." - #elif ENABLED(SCARA) + #if ENABLED(SCARA) #error "BABYSTEPPING is not implemented for SCARA yet." #elif ENABLED(DELTA) && ENABLED(BABYSTEP_XY) #error "BABYSTEPPING only implemented for Z axis on deltabots." @@ -424,6 +491,10 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, #endif #endif +#if ENABLED(LIN_ADVANCE) && !IS_CARTESIAN + #error "Sorry! LIN_ADVANCE is only compatible with Cartesian." +#endif + /** * Parking Extruder requirements */ @@ -532,14 +603,14 @@ static_assert(1 >= 0 * Delta requirements */ #if ENABLED(DELTA) - #if DISABLED(USE_XMAX_PLUG) && DISABLED(USE_YMAX_PLUG) && DISABLED(USE_ZMAX_PLUG) + #if HAS_BED_PROBE && ENABLED(Z_MIN_PROBE_ENDSTOP) + #error "Delta probably shouldn't use Z_MIN_PROBE_ENDSTOP. Comment out this line to continue." + #elif DISABLED(USE_XMAX_PLUG) && DISABLED(USE_YMAX_PLUG) && DISABLED(USE_ZMAX_PLUG) #error "You probably want to use Max Endstops for DELTA!" - #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_DELTA + #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_SEGMENTED #error "ENABLE_LEVELING_FADE_HEIGHT on DELTA requires AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." - #elif ENABLED(DELTA_AUTO_CALIBRATION) && !PROBE_SELECTED - #error "DELTA_AUTO_CALIBRATION requires a probe: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, Z Servo." - #elif ENABLED(DELTA_AUTO_CALIBRATION) && ENABLED(PROBE_MANUALLY) && DISABLED(ULTIPANEL) - #error "DELTA_AUTO_CALIBRATION requires an LCD controller with PROBE_MANUALLY." + #elif ENABLED(DELTA_AUTO_CALIBRATION) && !(HAS_BED_PROBE || ENABLED(ULTIPANEL)) + #error "DELTA_AUTO_CALIBRATION requires a probe or LCD Controller." #elif ABL_GRID #if (GRID_MAX_POINTS_X & 1) == 0 || (GRID_MAX_POINTS_Y & 1) == 0 #error "DELTA requires GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y to be odd numbers." @@ -581,7 +652,7 @@ static_assert(1 >= 0 , "Please enable only one probe option: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." ); -#if PROBE_SELECTED +#if HAS_BED_PROBE /** * Z_PROBE_SLED is incompatible with DELTA @@ -629,14 +700,14 @@ static_assert(1 >= 0 #if !HAS_Z_MIN_PROBE_PIN #error "Z_MIN_PROBE_ENDSTOP requires the Z_MIN_PROBE_PIN to be defined." #endif - #elif DISABLED(PROBE_MANUALLY) + #else #error "You must enable either Z_MIN_PROBE_ENDSTOP or Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN to use a probe." #endif /** * Make sure Z raise values are set */ - #if !defined(Z_CLEARANCE_DEPLOY_PROBE) + #ifndef Z_CLEARANCE_DEPLOY_PROBE #error "You must define Z_CLEARANCE_DEPLOY_PROBE in your configuration." #elif !defined(Z_CLEARANCE_BETWEEN_PROBES) #error "You must define Z_CLEARANCE_BETWEEN_PROBES in your configuration." @@ -646,19 +717,23 @@ static_assert(1 >= 0 #error "Probes need Z_CLEARANCE_BETWEEN_PROBES >= 0." #endif + #if MULTIPLE_PROBING && MULTIPLE_PROBING < 2 + #error "MULTIPLE_PROBING must be >= 2." + #endif + #else /** * Require some kind of probe for bed leveling and probe testing */ - #if HAS_ABL && DISABLED(AUTO_BED_LEVELING_UBL) + #if OLDSCHOOL_ABL && !PROBE_SELECTED #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo." #endif -#endif + #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe: FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." + #endif -#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) && !HAS_BED_PROBE - #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe: FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." #endif /** @@ -693,6 +768,9 @@ static_assert(1 >= 0 * Unified Bed Leveling */ + // Hide PROBE_MANUALLY from the rest of the code + #undef PROBE_MANUALLY + #if IS_SCARA #error "AUTO_BED_LEVELING_UBL does not yet support SCARA printers." #elif DISABLED(EEPROM_SETTINGS) @@ -708,7 +786,7 @@ static_assert(1 >= 0 static_assert(WITHIN(UBL_PROBE_PT_3_Y, MIN_PROBE_Y, MAX_PROBE_Y), "UBL_PROBE_PT_3_Y can't be reached by the Z probe."); #endif -#elif HAS_ABL +#elif OLDSCHOOL_ABL /** * Auto Bed Leveling @@ -757,26 +835,37 @@ static_assert(1 >= 0 #elif ENABLED(MESH_BED_LEVELING) + // Hide PROBE_MANUALLY from the rest of the code + #undef PROBE_MANUALLY + /** * Mesh Bed Leveling */ #if ENABLED(DELTA) - #error "MESH_BED_LEVELING does not yet support DELTA printers." + #error "MESH_BED_LEVELING is not compatible with DELTA printers." #elif GRID_MAX_POINTS_X > 9 || GRID_MAX_POINTS_Y > 9 #error "GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y must be less than 10 for MBL." #endif #endif +#if !HAS_MESH && ENABLED(G26_MESH_VALIDATION) + #error "G26_MESH_VALIDATION requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL." +#endif + +#if ENABLED(MESH_EDIT_GFX_OVERLAY) && (DISABLED(AUTO_BED_LEVELING_UBL) || DISABLED(DOGLCD)) + #error "MESH_EDIT_GFX_OVERLAY requires AUTO_BED_LEVELING_UBL and a Graphical LCD." +#endif + /** * LCD_BED_LEVELING requirements */ #if ENABLED(LCD_BED_LEVELING) #if DISABLED(ULTIPANEL) #error "LCD_BED_LEVELING requires an LCD controller." - #elif DISABLED(MESH_BED_LEVELING) && !(HAS_ABL && ENABLED(PROBE_MANUALLY)) - #error "LCD_BED_LEVELING requires MESH_BED_LEVELING or PROBE_MANUALLY with auto bed leveling enabled." + #elif !(ENABLED(MESH_BED_LEVELING) || (OLDSCHOOL_ABL && ENABLED(PROBE_MANUALLY))) + #error "LCD_BED_LEVELING requires MESH_BED_LEVELING or ABL with PROBE_MANUALLY." #endif #endif @@ -818,8 +907,12 @@ static_assert(1 >= 0 /** * Filament Width Sensor */ -#if ENABLED(FILAMENT_WIDTH_SENSOR) && !HAS_FILAMENT_WIDTH_SENSOR - #error "FILAMENT_WIDTH_SENSOR requires a FILWIDTH_PIN to be defined." +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #if !HAS_FILAMENT_WIDTH_SENSOR + #error "FILAMENT_WIDTH_SENSOR requires a FILWIDTH_PIN to be defined." + #elif ENABLED(NO_VOLUMETRICS) + #error "FILAMENT_WIDTH_SENSOR requires NO_VOLUMETRICS to be disabled." + #endif #endif /** @@ -915,10 +1008,11 @@ static_assert(1 >= 0 #error "TEMP_SENSOR_0 is required." #endif -#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) - #if !HAS_HEATER_1 - #error "HEATER_1_PIN not defined for this board." - #endif +// Pins are required for heaters +#if ENABLED(HEATER_0_USES_MAX6675) && !(defined(MAX6675_SS) && MAX6675_SS >= 0) + #error "MAX6675_SS (required for TEMP_SENSOR_0) not defined for this board." +#elif (HOTENDS > 1 || ENABLED(HEATERS_PARALLEL)) && !HAS_HEATER_1 + #error "HEATER_1_PIN not defined for this board." #endif #if HOTENDS > 1 @@ -1007,42 +1101,45 @@ static_assert(1 >= 0 /** * Test Extruder Stepper Pins */ -#if E_STEPPERS > 4 - #if !PIN_EXISTS(E4_STEP) || !PIN_EXISTS(E4_DIR) || !PIN_EXISTS(E4_ENABLE) - #error "E4_STEP_PIN, E4_DIR_PIN, or E4_ENABLE_PIN not defined for this board." - #endif -#elif E_STEPPERS > 3 - #if !PIN_EXISTS(E3_STEP) || !PIN_EXISTS(E3_DIR) || !PIN_EXISTS(E3_ENABLE) - #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board." - #endif -#elif E_STEPPERS > 2 - #if !PIN_EXISTS(E2_STEP) || !PIN_EXISTS(E2_DIR) || !PIN_EXISTS(E2_ENABLE) - #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board." - #endif -#elif E_STEPPERS > 1 - #if !PIN_EXISTS(E1_STEP) || !PIN_EXISTS(E1_DIR) || !PIN_EXISTS(E1_ENABLE) - #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board." +#if DISABLED(MK2_MULTIPLEXER) // MK2_MULTIPLEXER uses E0 stepper only + #if E_STEPPERS > 4 + #if !PIN_EXISTS(E4_STEP) || !PIN_EXISTS(E4_DIR) || !PIN_EXISTS(E4_ENABLE) + #error "E4_STEP_PIN, E4_DIR_PIN, or E4_ENABLE_PIN not defined for this board." + #endif + #elif E_STEPPERS > 3 + #if !PIN_EXISTS(E3_STEP) || !PIN_EXISTS(E3_DIR) || !PIN_EXISTS(E3_ENABLE) + #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board." + #endif + #elif E_STEPPERS > 2 + #if !PIN_EXISTS(E2_STEP) || !PIN_EXISTS(E2_DIR) || !PIN_EXISTS(E2_ENABLE) + #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board." + #endif + #elif E_STEPPERS > 1 + #if !PIN_EXISTS(E1_STEP) || !PIN_EXISTS(E1_DIR) || !PIN_EXISTS(E1_ENABLE) + #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board." + #endif #endif #endif - /** - * Endstops + * Endstop Tests */ -#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _XMAX_, _XMIN_)) - #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." -#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _YMAX_, _YMIN_)) - #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." -#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _ZMAX_, _ZMIN_)) - #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." -#elif ENABLED(Z_DUAL_ENDSTOPS) - #if !Z2_USE_ENDSTOP - #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS." - #elif Z2_MAX_PIN == 0 && Z2_MIN_PIN == 0 - #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!" - #elif ENABLED(DELTA) - #error "Z_DUAL_ENDSTOPS is not compatible with DELTA." - #endif -#elif !IS_SCARA + +#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG) && DISABLED(USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_))) +#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z)) + +// At least 3 endstop plugs must be used +#if _AXIS_PLUG_UNUSED_TEST(X) + #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." +#endif +#if _AXIS_PLUG_UNUSED_TEST(Y) + #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." +#endif +#if _AXIS_PLUG_UNUSED_TEST(Z) + #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." +#endif + +// Delta and Cartesian use 3 homing endstops +#if !IS_SCARA #if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG) #error "Enable USE_XMIN_PLUG when homing X to MIN." #elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG) @@ -1051,10 +1148,76 @@ static_assert(1 >= 0 #error "Enable USE_YMIN_PLUG when homing Y to MIN." #elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG) #error "Enable USE_YMAX_PLUG when homing Y to MAX." - #elif Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) - #error "Enable USE_ZMIN_PLUG when homing Z to MIN." - #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) - #error "Enable USE_ZMAX_PLUG when homing Z to MAX." + #endif +#endif +#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) + #error "Enable USE_ZMIN_PLUG when homing Z to MIN." +#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) + #error "Enable USE_ZMAX_PLUG when homing Z to MAX." +#endif + +// Dual endstops requirements +#if ENABLED(X_DUAL_ENDSTOPS) + #if !X2_USE_ENDSTOP + #error "You must set X2_USE_ENDSTOP with X_DUAL_ENDSTOPS." + #elif X2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when X2_USE_ENDSTOP is _X_MIN_." + #elif X2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when X2_USE_ENDSTOP is _X_MAX_." + #elif X2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when X2_USE_ENDSTOP is _Y_MIN_." + #elif X2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when X2_USE_ENDSTOP is _Y_MAX_." + #elif X2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when X2_USE_ENDSTOP is _Z_MIN_." + #elif X2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when X2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_X2_MIN && !HAS_X2_MAX + #error "X2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "X_DUAL_ENDSTOPS is not compatible with DELTA." + #endif +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + #if !Y2_USE_ENDSTOP + #error "You must set Y2_USE_ENDSTOP with Y_DUAL_ENDSTOPS." + #elif Y2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when Y2_USE_ENDSTOP is _X_MIN_." + #elif Y2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when Y2_USE_ENDSTOP is _X_MAX_." + #elif Y2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when Y2_USE_ENDSTOP is _Y_MIN_." + #elif Y2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when Y2_USE_ENDSTOP is _Y_MAX_." + #elif Y2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when Y2_USE_ENDSTOP is _Z_MIN_." + #elif Y2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when Y2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_Y2_MIN && !HAS_Y2_MAX + #error "Y2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "Y_DUAL_ENDSTOPS is not compatible with DELTA." + #endif +#endif +#if ENABLED(Z_DUAL_ENDSTOPS) + #if !Z2_USE_ENDSTOP + #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS." + #elif Z2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when Z2_USE_ENDSTOP is _X_MIN_." + #elif Z2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when Z2_USE_ENDSTOP is _X_MAX_." + #elif Z2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when Z2_USE_ENDSTOP is _Y_MIN_." + #elif Z2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when Z2_USE_ENDSTOP is _Y_MAX_." + #elif Z2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when Z2_USE_ENDSTOP is _Z_MIN_." + #elif Z2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when Z2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_Z2_MIN && !HAS_Z2_MAX + #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "Z_DUAL_ENDSTOPS is not compatible with DELTA." #endif #endif @@ -1132,6 +1295,7 @@ static_assert(1 >= 0 * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER => REPRAP_DISCOUNT_SMART_CONTROLLER * SAV_3DGLCD => U8GLIB_SH1106 => ULTIMAKERCONTROLLER * MKS_12864OLED => U8GLIB_SH1106 => ULTIMAKERCONTROLLER + * MKS_12864OLED_SSD1306 => U8GLIB_SSD1306 => ULTIMAKERCONTROLLER * miniVIKI => ULTIMAKERCONTROLLER * VIKI2 => ULTIMAKERCONTROLLER * ELB_FULL_GRAPHIC_CONTROLLER => ULTIMAKERCONTROLLER @@ -1144,14 +1308,16 @@ static_assert(1 >= 0 && DISABLED(VIKI2) \ && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ && DISABLED(PANEL_ONE) \ - && DISABLED(MKS_12864OLED) + && DISABLED(MKS_12864OLED) \ + && DISABLED(MKS_12864OLED_SSD1306) + 1 #endif #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \ && DISABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \ && DISABLED(LCD_FOR_MELZI) \ && DISABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \ - && DISABLED(MKS_12864OLED) + && DISABLED(MKS_12864OLED) \ + && DISABLED(MKS_12864OLED_SSD1306) + 1 #endif #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \ @@ -1164,6 +1330,9 @@ static_assert(1 >= 0 #if ENABLED(MKS_12864OLED) + 1 #endif + #if ENABLED(MKS_12864OLED_SSD1306) + + 1 + #endif #if ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) + 1 #endif @@ -1199,7 +1368,7 @@ static_assert(1 >= 0 #endif #if ENABLED(REPRAPWORLD_KEYPAD) \ && DISABLED(CARTESIO_UI) \ - && DISABLED(ANET_KEYPAD_LCD) + && DISABLED(ZONESTAR_LCD) + 1 #endif #if ENABLED(RIGIDBOT_PANEL) @@ -1220,7 +1389,7 @@ static_assert(1 >= 0 #if ENABLED(LCD_I2C_VIKI) + 1 #endif - #if ENABLED(U8GLIB_SSD1306) && DISABLED(OLED_PANEL_TINYBOY2) + #if ENABLED(U8GLIB_SSD1306) && DISABLED(OLED_PANEL_TINYBOY2) && DISABLED(MKS_12864OLED_SSD1306) + 1 #endif #if ENABLED(SAV_3DLCD) @@ -1235,7 +1404,7 @@ static_assert(1 >= 0 #if ENABLED(OLED_PANEL_TINYBOY2) + 1 #endif - #if ENABLED(ANET_KEYPAD_LCD) + #if ENABLED(ZONESTAR_LCD) + 1 #endif , "Please select no more than one LCD controller option." @@ -1274,14 +1443,37 @@ static_assert(1 >= 0 || ENABLED( E1_IS_TMC2130 ) \ || ENABLED( E2_IS_TMC2130 ) \ || ENABLED( E3_IS_TMC2130 ) \ - || ENABLED( E4_IS_TMC2130 ) \ - ) + || ENABLED( E4_IS_TMC2130 ) ) #error "HAVE_TMC2130 requires at least one TMC2130 stepper to be set." #elif ENABLED(HYBRID_THRESHOLD) && DISABLED(STEALTHCHOP) #error "Enable STEALTHCHOP to use HYBRID_THRESHOLD." + #elif defined(AUTOMATIC_CURRENT_CONTROL) + #error "AUTOMATIC_CURRENT_CONTROL is now MONITOR_DRIVER_STATUS. Please update your configuration." #endif #endif +/** + * Make sure HAVE_TMC2208 is warranted + */ + +#if ENABLED(HAVE_TMC2208) && !( \ + ENABLED( X_IS_TMC2208 ) \ + || ENABLED( X2_IS_TMC2208 ) \ + || ENABLED( Y_IS_TMC2208 ) \ + || ENABLED( Y2_IS_TMC2208 ) \ + || ENABLED( Z_IS_TMC2208 ) \ + || ENABLED( Z2_IS_TMC2208 ) \ + || ENABLED( E0_IS_TMC2208 ) \ + || ENABLED( E1_IS_TMC2208 ) \ + || ENABLED( E2_IS_TMC2208 ) \ + || ENABLED( E3_IS_TMC2208 ) ) + #error "HAVE_TMC2208 requires at least one TMC2208 stepper to be set." +#endif + +#if ENABLED(HYBRID_THRESHOLD) && DISABLED(STEALTHCHOP) + #error "Enable STEALTHCHOP to use HYBRID_THRESHOLD." +#endif + /** * Make sure HAVE_L6470DRIVER is warranted */ @@ -1384,3 +1576,31 @@ static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too m #endif #endif #endif // SPINDLE_LASER_ENABLE + +#if ENABLED(CNC_COORDINATE_SYSTEMS) && ENABLED(NO_WORKSPACE_OFFSETS) + #error "CNC_COORDINATE_SYSTEMS is incompatible with NO_WORKSPACE_OFFSETS." +#endif + +#if !BLOCK_BUFFER_SIZE || !IS_POWER_OF_2(BLOCK_BUFFER_SIZE) + #error "BLOCK_BUFFER_SIZE must be a power of 2." +#endif + +#if ENABLED(LED_CONTROL_MENU) && DISABLED(ULTIPANEL) + #error "LED_CONTROL_MENU requires an LCD controller." +#endif + +#if ENABLED(SKEW_CORRECTION) + #if !defined(XY_SKEW_FACTOR) && !(defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD)) + #error "SKEW_CORRECTION requires XY_SKEW_FACTOR or XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD." + #endif + #if ENABLED(SKEW_CORRECTION_FOR_Z) + #if !defined(XZ_SKEW_FACTOR) && !(defined(XZ_DIAG_AC) && defined(XZ_DIAG_BD) && defined(XZ_SIDE_AD)) + #error "SKEW_CORRECTION requires XZ_SKEW_FACTOR or XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD." + #endif + #if !defined(YZ_SKEW_FACTOR) && !(defined(YZ_DIAG_AC) && defined(YZ_DIAG_BD) && defined(YZ_SIDE_AD)) + #error "SKEW_CORRECTION requires YZ_SKEW_FACTOR or YZ_DIAG_AC, YZ_DIAG_BD, YZ_SIDE_AD." + #endif + #endif +#endif + +#endif // _SANITYCHECK_H_ diff --git a/Marlin/Sd2Card.cpp b/Marlin/Sd2Card.cpp index 2afe9a8b48..6683e4b4fd 100644 --- a/Marlin/Sd2Card.cpp +++ b/Marlin/Sd2Card.cpp @@ -26,19 +26,19 @@ * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(SDSUPPORT) + #include "Sd2Card.h" #if ENABLED(USE_WATCHDOG) #include "watchdog.h" #endif -//------------------------------------------------------------------------------ #if DISABLED(SOFTWARE_SPI) // functions for hardware SPI - //------------------------------------------------------------------------------ + // make sure SPCR rate is in expected bits #if (SPR0 != 0 || SPR1 != 1) #error "unexpected SPCR bits" @@ -52,14 +52,14 @@ SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1); SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X); } - //------------------------------------------------------------------------------ + /** SPI receive a byte */ static uint8_t spiRec() { SPDR = 0xFF; while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } return SPDR; } - //------------------------------------------------------------------------------ + /** SPI read data - only one call so force inline */ static inline __attribute__((always_inline)) void spiRead(uint8_t* buf, uint16_t nbyte) { @@ -73,13 +73,13 @@ while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } buf[nbyte] = SPDR; } - //------------------------------------------------------------------------------ + /** SPI send a byte */ static void spiSend(uint8_t b) { SPDR = b; while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } } - //------------------------------------------------------------------------------ + /** SPI send block - only one call so force inline */ static inline __attribute__((always_inline)) void spiSendBlock(uint8_t token, const uint8_t* buf) { @@ -95,9 +95,10 @@ //------------------------------------------------------------------------------ #else // SOFTWARE_SPI //------------------------------------------------------------------------------ + /** nop to tune soft SPI timing */ #define nop asm volatile ("nop\n\t") - //------------------------------------------------------------------------------ + /** Soft SPI receive byte */ static uint8_t spiRec() { uint8_t data = 0; @@ -123,13 +124,13 @@ sei(); return data; } - //------------------------------------------------------------------------------ + /** Soft SPI read data */ static void spiRead(uint8_t* buf, uint16_t nbyte) { for (uint16_t i = 0; i < nbyte; i++) buf[i] = spiRec(); } - //------------------------------------------------------------------------------ + /** Soft SPI send byte */ static void spiSend(uint8_t data) { // no interrupts during byte send - about 8 us @@ -153,7 +154,7 @@ // enable interrupts sei(); } - //------------------------------------------------------------------------------ + /** Soft SPI send block */ void spiSendBlock(uint8_t token, const uint8_t* buf) { spiSend(token); @@ -161,7 +162,7 @@ spiSend(buf[i]); } #endif // SOFTWARE_SPI -//------------------------------------------------------------------------------ + // send command and return error code. Return zero for OK uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { // select card @@ -189,7 +190,7 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { for (uint8_t i = 0; ((status_ = spiRec()) & 0x80) && i != 0xFF; i++) { /* Intentionally left empty */ } return status_; } -//------------------------------------------------------------------------------ + /** * Determine the size of an SD flash memory card. * @@ -217,19 +218,20 @@ uint32_t Sd2Card::cardSize() { return 0; } } -//------------------------------------------------------------------------------ + void Sd2Card::chipSelectHigh() { digitalWrite(chipSelectPin_, HIGH); } -//------------------------------------------------------------------------------ + void Sd2Card::chipSelectLow() { #if DISABLED(SOFTWARE_SPI) spiInit(spiRate_); #endif // SOFTWARE_SPI digitalWrite(chipSelectPin_, LOW); } -//------------------------------------------------------------------------------ -/** Erase a range of blocks. + +/** + * Erase a range of blocks. * * \param[in] firstBlock The address of the first block in the range. * \param[in] lastBlock The address of the last block in the range. @@ -239,8 +241,7 @@ void Sd2Card::chipSelectLow() { * either 0 or 1, depends on the card vendor. The card must support * single block erase. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { csd_t csd; @@ -275,26 +276,26 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { chipSelectHigh(); return false; } -//------------------------------------------------------------------------------ -/** Determine if card supports single block erase. + +/** + * Determine if card supports single block erase. * - * \return The value one, true, is returned if single block erase is supported. - * The value zero, false, is returned if single block erase is not supported. + * \return true if single block erase is supported. + * false if single block erase is not supported. */ bool Sd2Card::eraseSingleBlockEnable() { csd_t csd; return readCSD(&csd) ? csd.v1.erase_blk_en : false; } -//------------------------------------------------------------------------------ + /** * Initialize an SD flash memory card. * * \param[in] sckRateID SPI clock rate selector. See setSckRate(). * \param[in] chipSelectPin SD chip select pin number. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. The reason for failure - * can be determined by calling errorCode() and errorData(). + * \return true for success, false for failure. + * The reason for failure can be determined by calling errorCode() and errorData(). */ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { errorCode_ = type_ = 0; @@ -384,14 +385,13 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { chipSelectHigh(); return false; } -//------------------------------------------------------------------------------ + /** * Read a 512 byte block from an SD card. * * \param[in] blockNumber Logical block to be read. * \param[out] dst Pointer to the location that will receive the data. - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { // use address if not SDHC card @@ -399,19 +399,18 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { #if ENABLED(SD_CHECK_AND_RETRY) uint8_t retryCnt = 3; - do { - if (!cardCommand(CMD17, blockNumber)) { - if (readData(dst, 512)) return true; - } - else + for(;;) { + if (cardCommand(CMD17, blockNumber)) error(SD_CARD_ERROR_CMD17); + else if (readData(dst, 512)) + return true; if (!--retryCnt) break; chipSelectHigh(); cardCommand(CMD12, 0); // Try sending a stop command, ignore the result. errorCode_ = 0; - } while (true); + } #else if (cardCommand(CMD17, blockNumber)) error(SD_CARD_ERROR_CMD17); @@ -422,13 +421,13 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { chipSelectHigh(); return false; } -//------------------------------------------------------------------------------ -/** Read one data block in a multiple block read sequence + +/** + * Read one data block in a multiple block read sequence * * \param[in] dst Pointer to the location for the data to be read. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::readData(uint8_t* dst) { chipSelectLow(); @@ -436,50 +435,49 @@ bool Sd2Card::readData(uint8_t* dst) { } #if ENABLED(SD_CHECK_AND_RETRY) -static const uint16_t crctab[] PROGMEM = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 -}; -static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { - uint16_t crc = 0; - for (size_t i = 0; i < n; i++) { - crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8); + static const uint16_t crctab[] PROGMEM = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 + }; + static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8); + } + return crc; } - return crc; -} -#endif +#endif // SD_CHECK_AND_RETRY -//------------------------------------------------------------------------------ bool Sd2Card::readData(uint8_t* dst, uint16_t count) { // wait for start block token uint16_t t0 = millis(); @@ -521,61 +519,55 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) { spiSend(0XFF); return false; } -//------------------------------------------------------------------------------ + /** read CID or CSR register */ bool Sd2Card::readRegister(uint8_t cmd, void* buf) { uint8_t* dst = reinterpret_cast(buf); if (cardCommand(cmd, 0)) { error(SD_CARD_ERROR_READ_REG); - goto FAIL; + chipSelectHigh(); + return false; } return readData(dst, 16); - FAIL: - chipSelectHigh(); - return false; } -//------------------------------------------------------------------------------ -/** Start a read multiple blocks sequence. + +/** + * Start a read multiple blocks sequence. * * \param[in] blockNumber Address of first block in sequence. * * \note This function is used with readData() and readStop() for optimized * multiple block reads. SPI chipSelect must be low for the entire sequence. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::readStart(uint32_t blockNumber) { if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (cardCommand(CMD18, blockNumber)) { error(SD_CARD_ERROR_CMD18); - goto FAIL; + chipSelectHigh(); + return false; } chipSelectHigh(); return true; - FAIL: - chipSelectHigh(); - return false; } -//------------------------------------------------------------------------------ -/** End a read multiple blocks sequence. + +/** + * End a read multiple blocks sequence. * -* \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::readStop() { chipSelectLow(); if (cardCommand(CMD12, 0)) { error(SD_CARD_ERROR_CMD12); - goto FAIL; + chipSelectHigh(); + return false; } chipSelectHigh(); return true; - FAIL: - chipSelectHigh(); - return false; } -//------------------------------------------------------------------------------ + /** * Set the SPI clock rate. * @@ -596,25 +588,22 @@ bool Sd2Card::setSckRate(uint8_t sckRateID) { spiRate_ = sckRateID; return true; } -//------------------------------------------------------------------------------ + // wait for card to go not busy bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { uint16_t t0 = millis(); - while (spiRec() != 0XFF) { - if (((uint16_t)millis() - t0) >= timeoutMillis) goto FAIL; - } + while (spiRec() != 0XFF) + if (((uint16_t)millis() - t0) >= timeoutMillis) return false; + return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + /** * Writes a 512 byte block to an SD card. * * \param[in] blockNumber Logical block to be written. * \param[in] src Pointer to the location of the data to be written. - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { // use address if not SDHC card @@ -641,25 +630,24 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { chipSelectHigh(); return false; } -//------------------------------------------------------------------------------ -/** Write one data block in a multiple block write sequence + +/** + * Write one data block in a multiple block write sequence * \param[in] src Pointer to the location of the data to be written. - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::writeData(const uint8_t* src) { chipSelectLow(); // wait for previous write to finish - if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; - if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto FAIL; + if (!waitNotBusy(SD_WRITE_TIMEOUT) || !writeData(WRITE_MULTIPLE_TOKEN, src)) { + error(SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; + } chipSelectHigh(); return true; - FAIL: - error(SD_CARD_ERROR_WRITE_MULTIPLE); - chipSelectHigh(); - return false; } -//------------------------------------------------------------------------------ + // send one block of data for write block or write multiple blocks bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { spiSendBlock(token, src); @@ -670,15 +658,14 @@ bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { status_ = spiRec(); if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { error(SD_CARD_ERROR_WRITE); - goto FAIL; + chipSelectHigh(); + return false; } return true; - FAIL: - chipSelectHigh(); - return false; } -//------------------------------------------------------------------------------ -/** Start a write multiple blocks sequence. + +/** + * Start a write multiple blocks sequence. * * \param[in] blockNumber Address of first block in sequence. * \param[in] eraseCount The number of blocks to be pre-erased. @@ -686,8 +673,7 @@ bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { * \note This function is used with writeData() and writeStop() * for optimized multiple block writes. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { // send pre-erase count @@ -707,11 +693,11 @@ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { chipSelectHigh(); return false; } -//------------------------------------------------------------------------------ -/** End a write multiple blocks sequence. + +/** + * End a write multiple blocks sequence. * -* \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool Sd2Card::writeStop() { chipSelectLow(); @@ -726,4 +712,4 @@ bool Sd2Card::writeStop() { return false; } -#endif +#endif // SDSUPPORT diff --git a/Marlin/Sd2Card.h b/Marlin/Sd2Card.h index 1fbd527473..9849980a25 100644 --- a/Marlin/Sd2Card.h +++ b/Marlin/Sd2Card.h @@ -20,165 +20,119 @@ * */ +/** + * \file + * \brief Sd2Card class for V2 SD/SDHC cards + */ + /** * Arduino Sd2Card Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ +#ifndef _SD2CARD_H_ +#define _SD2CARD_H_ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) - -#ifndef Sd2Card_h -#define Sd2Card_h -/** - * \file - * \brief Sd2Card class for V2 SD/SDHC cards - */ #include "SdFatConfig.h" #include "SdInfo.h" -//------------------------------------------------------------------------------ + // SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6 -/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ -uint8_t const SPI_FULL_SPEED = 0; -/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ -uint8_t const SPI_HALF_SPEED = 1; -/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */ -uint8_t const SPI_QUARTER_SPEED = 2; -/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */ -uint8_t const SPI_EIGHTH_SPEED = 3; -/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */ -uint8_t const SPI_SIXTEENTH_SPEED = 4; -//------------------------------------------------------------------------------ -/** init timeout ms */ -uint16_t const SD_INIT_TIMEOUT = 2000; -/** erase timeout ms */ -uint16_t const SD_ERASE_TIMEOUT = 10000; -/** read timeout ms */ -uint16_t const SD_READ_TIMEOUT = 300; -/** write time out ms */ -uint16_t const SD_WRITE_TIMEOUT = 600; -//------------------------------------------------------------------------------ +uint8_t const SPI_FULL_SPEED = 0, // Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). + SPI_HALF_SPEED = 1, // Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). + SPI_QUARTER_SPEED = 2, // Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). + SPI_EIGHTH_SPEED = 3, // Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). + SPI_SIXTEENTH_SPEED = 4; // Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). + +uint16_t const SD_INIT_TIMEOUT = 2000, // init timeout ms + SD_ERASE_TIMEOUT = 10000, // erase timeout ms + SD_READ_TIMEOUT = 300, // read timeout ms + SD_WRITE_TIMEOUT = 600; // write time out ms + // SD card errors -/** timeout error for command CMD0 (initialize card in SPI mode) */ -uint8_t const SD_CARD_ERROR_CMD0 = 0X1; -/** CMD8 was not accepted - not a valid SD card*/ -uint8_t const SD_CARD_ERROR_CMD8 = 0X2; -/** card returned an error response for CMD12 (write stop) */ -uint8_t const SD_CARD_ERROR_CMD12 = 0X3; -/** card returned an error response for CMD17 (read block) */ -uint8_t const SD_CARD_ERROR_CMD17 = 0X4; -/** card returned an error response for CMD18 (read multiple block) */ -uint8_t const SD_CARD_ERROR_CMD18 = 0X5; -/** card returned an error response for CMD24 (write block) */ -uint8_t const SD_CARD_ERROR_CMD24 = 0X6; -/** WRITE_MULTIPLE_BLOCKS command failed */ -uint8_t const SD_CARD_ERROR_CMD25 = 0X7; -/** card returned an error response for CMD58 (read OCR) */ -uint8_t const SD_CARD_ERROR_CMD58 = 0X8; -/** SET_WR_BLK_ERASE_COUNT failed */ -uint8_t const SD_CARD_ERROR_ACMD23 = 0X9; -/** ACMD41 initialization process timeout */ -uint8_t const SD_CARD_ERROR_ACMD41 = 0XA; -/** card returned a bad CSR version field */ -uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB; -/** erase block group command failed */ -uint8_t const SD_CARD_ERROR_ERASE = 0XC; -/** card not capable of single block erase */ -uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD; -/** Erase sequence timed out */ -uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE; -/** card returned an error token instead of read data */ -uint8_t const SD_CARD_ERROR_READ = 0XF; -/** read CID or CSD failed */ -uint8_t const SD_CARD_ERROR_READ_REG = 0x10; -/** timeout while waiting for start of read data */ -uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0x11; -/** card did not accept STOP_TRAN_TOKEN */ -uint8_t const SD_CARD_ERROR_STOP_TRAN = 0x12; -/** card returned an error token as a response to a write operation */ -uint8_t const SD_CARD_ERROR_WRITE = 0x13; -/** attempt to write protected block zero */ -uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14; // REMOVE - not used -/** card did not go ready for a multiple block write */ -uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0x15; -/** card returned an error to a CMD13 status check after a write */ -uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16; -/** timeout occurred during write programming */ -uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0x17; -/** incorrect rate selected */ -uint8_t const SD_CARD_ERROR_SCK_RATE = 0x18; -/** init() not called */ -uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0x19; -/** crc check error */ -uint8_t const SD_CARD_ERROR_CRC = 0x20; -//------------------------------------------------------------------------------ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1, // timeout error for command CMD0 (initialize card in SPI mode) + SD_CARD_ERROR_CMD8 = 0X2, // CMD8 was not accepted - not a valid SD card + SD_CARD_ERROR_CMD12 = 0X3, // card returned an error response for CMD12 (write stop) + SD_CARD_ERROR_CMD17 = 0X4, // card returned an error response for CMD17 (read block) + SD_CARD_ERROR_CMD18 = 0X5, // card returned an error response for CMD18 (read multiple block) + SD_CARD_ERROR_CMD24 = 0X6, // card returned an error response for CMD24 (write block) + SD_CARD_ERROR_CMD25 = 0X7, // WRITE_MULTIPLE_BLOCKS command failed + SD_CARD_ERROR_CMD58 = 0X8, // card returned an error response for CMD58 (read OCR) + SD_CARD_ERROR_ACMD23 = 0X9, // SET_WR_BLK_ERASE_COUNT failed + SD_CARD_ERROR_ACMD41 = 0XA, // ACMD41 initialization process timeout + SD_CARD_ERROR_BAD_CSD = 0XB, // card returned a bad CSR version field + SD_CARD_ERROR_ERASE = 0XC, // erase block group command failed + SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD, // card not capable of single block erase + SD_CARD_ERROR_ERASE_TIMEOUT = 0XE, // Erase sequence timed out + SD_CARD_ERROR_READ = 0XF, // card returned an error token instead of read data + SD_CARD_ERROR_READ_REG = 0x10, // read CID or CSD failed + SD_CARD_ERROR_READ_TIMEOUT = 0x11, // timeout while waiting for start of read data + SD_CARD_ERROR_STOP_TRAN = 0x12, // card did not accept STOP_TRAN_TOKEN + SD_CARD_ERROR_WRITE = 0x13, // card returned an error token as a response to a write operation + SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero + SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // card did not go ready for a multiple block write + SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // card returned an error to a CMD13 status check after a write + SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // timeout occurred during write programming + SD_CARD_ERROR_SCK_RATE = 0x18, // incorrect rate selected + SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // init() not called + SD_CARD_ERROR_CRC = 0x20; // crc check error + // card types -/** Standard capacity V1 SD card */ -uint8_t const SD_CARD_TYPE_SD1 = 1; -/** Standard capacity V2 SD card */ -uint8_t const SD_CARD_TYPE_SD2 = 2; -/** High Capacity SD card */ -uint8_t const SD_CARD_TYPE_SDHC = 3; +uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card + SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card + SD_CARD_TYPE_SDHC = 3; // High Capacity SD card + /** * define SOFTWARE_SPI to use bit-bang SPI */ -//------------------------------------------------------------------------------ #if MEGA_SOFT_SPI #define SOFTWARE_SPI #elif USE_SOFTWARE_SPI #define SOFTWARE_SPI -#endif // MEGA_SOFT_SPI -//------------------------------------------------------------------------------ +#endif + // SPI pin definitions - do not edit here - change in SdFatConfig.h -// #if DISABLED(SOFTWARE_SPI) // hardware pin defs - /** The default chip select pin for the SD card is SS. */ - #define SD_CHIP_SELECT_PIN SS_PIN + #define SD_CHIP_SELECT_PIN SS_PIN // The default chip select pin for the SD card is SS. // The following three pins must not be redefined for hardware SPI. - /** SPI Master Out Slave In pin */ - #define SPI_MOSI_PIN MOSI_PIN - /** SPI Master In Slave Out pin */ - #define SPI_MISO_PIN MISO_PIN - /** SPI Clock pin */ - #define SPI_SCK_PIN SCK_PIN - + #define SPI_MOSI_PIN MOSI_PIN // SPI Master Out Slave In pin + #define SPI_MISO_PIN MISO_PIN // SPI Master In Slave Out pin + #define SPI_SCK_PIN SCK_PIN // SPI Clock pin #else // SOFTWARE_SPI - - /** SPI chip select pin */ - #define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN - /** SPI Master Out Slave In pin */ - #define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN - /** SPI Master In Slave Out pin */ - #define SPI_MISO_PIN SOFT_SPI_MISO_PIN - /** SPI Clock pin */ - #define SPI_SCK_PIN SOFT_SPI_SCK_PIN + #define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN // SPI chip select pin + #define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN // SPI Master Out Slave In pin + #define SPI_MISO_PIN SOFT_SPI_MISO_PIN // SPI Master In Slave Out pin + #define SPI_SCK_PIN SOFT_SPI_SCK_PIN // SPI Clock pin #endif // SOFTWARE_SPI -//------------------------------------------------------------------------------ + /** * \class Sd2Card * \brief Raw access to SD and SDHC flash memory cards. */ class Sd2Card { - public: - /** Construct an instance of Sd2Card. */ + public: + Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + uint32_t cardSize(); bool erase(uint32_t firstBlock, uint32_t lastBlock); bool eraseSingleBlockEnable(); + /** * Set SD error code. * \param[in] code value for error code. */ void error(uint8_t code) {errorCode_ = code;} + /** * \return error code for last error. See Sd2Card.h for a list of error codes. */ int errorCode() const {return errorCode_;} + /** \return error data for last error. */ int errorData() const {return status_;} + /** * Initialize an SD flash memory card with default clock rate and chip * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). @@ -188,6 +142,7 @@ class Sd2Card { bool init(uint8_t sckRateID = SPI_FULL_SPEED, uint8_t chipSelectPin = SD_CHIP_SELECT_PIN); bool readBlock(uint32_t block, uint8_t* dst); + /** * Read a card's CID register. The CID contains card identification * information such as Manufacturer ID, Product name, Product serial @@ -197,9 +152,8 @@ class Sd2Card { * * \return true for success or false for failure. */ - bool readCID(cid_t* cid) { - return readRegister(CMD10, cid); - } + bool readCID(cid_t* cid) { return readRegister(CMD10, cid); } + /** * Read a card's CSD register. The CSD contains Card-Specific Data that * provides information regarding access to the card's contents. @@ -208,14 +162,14 @@ class Sd2Card { * * \return true for success or false for failure. */ - bool readCSD(csd_t* csd) { - return readRegister(CMD9, csd); - } + bool readCSD(csd_t* csd) { return readRegister(CMD9, csd); } + bool readData(uint8_t* dst); bool readStart(uint32_t blockNumber); bool readStop(); bool setSckRate(uint8_t sckRateID); - /** Return the card type: SD V1, SD V2 or SDHC + /** + * Return the card type: SD V1, SD V2 or SDHC * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. */ int type() const {return type_;} @@ -223,13 +177,14 @@ class Sd2Card { bool writeData(const uint8_t* src); bool writeStart(uint32_t blockNumber, uint32_t eraseCount); bool writeStop(); - private: - //---------------------------------------------------------------------------- - uint8_t chipSelectPin_; - uint8_t errorCode_; - uint8_t spiRate_; - uint8_t status_; - uint8_t type_; + + private: + uint8_t chipSelectPin_, + errorCode_, + spiRate_, + status_, + type_; + // private functions uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { cardCommand(CMD55, 0); @@ -241,11 +196,9 @@ class Sd2Card { bool readRegister(uint8_t cmd, void* buf); void chipSelectHigh(); void chipSelectLow(); - void type(uint8_t value) {type_ = value;} + void type(uint8_t value) { type_ = value; } bool waitNotBusy(uint16_t timeoutMillis); bool writeData(uint8_t token, const uint8_t* src); }; -#endif // Sd2Card_h - -#endif +#endif // _SD2CARD_H_ diff --git a/Marlin/SdBaseFile.cpp b/Marlin/SdBaseFile.cpp index 95fc2b62b6..c1d8012e27 100644 --- a/Marlin/SdBaseFile.cpp +++ b/Marlin/SdBaseFile.cpp @@ -27,19 +27,21 @@ * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" +#include "MarlinConfig.h" + #if ENABLED(SDSUPPORT) #include "SdBaseFile.h" -//------------------------------------------------------------------------------ -// pointer to cwd directory -SdBaseFile* SdBaseFile::cwd_ = 0; +#include "Marlin.h" + +SdBaseFile* SdBaseFile::cwd_ = 0; // Pointer to Current Working Directory + // callback function for date/time void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; -//------------------------------------------------------------------------------ + // add a cluster to a file bool SdBaseFile::addCluster() { - if (!vol_->allocContiguous(1, &curCluster_)) goto FAIL; + if (!vol_->allocContiguous(1, &curCluster_)) return false; // if first cluster of file link to directory entry if (firstCluster_ == 0) { @@ -47,20 +49,17 @@ bool SdBaseFile::addCluster() { flags_ |= F_FILE_DIR_DIRTY; } return true; - - FAIL: - return false; } -//------------------------------------------------------------------------------ + // Add a cluster to a directory file and zero the cluster. // return with first block of cluster in the cache bool SdBaseFile::addDirCluster() { uint32_t block; // max folder size - if (fileSize_ / sizeof(dir_t) >= 0xFFFF) goto FAIL; + if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false; - if (!addCluster()) goto FAIL; - if (!vol_->cacheFlush()) goto FAIL; + if (!addCluster()) return false; + if (!vol_->cacheFlush()) return false; block = vol_->clusterStartBlock(curCluster_); @@ -72,29 +71,25 @@ bool SdBaseFile::addDirCluster() { // zero rest of cluster for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { - if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto FAIL; + if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) return false; } // Increase directory file size by cluster size fileSize_ += 512UL << vol_->clusterSizeShift_; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + // cache a file's directory entry // return pointer to cached entry or null for failure dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { - if (!vol_->cacheRawBlock(dirBlock_, action)) goto FAIL; + if (!vol_->cacheRawBlock(dirBlock_, action)) return NULL; return vol_->cache()->dir + dirIndex_; - FAIL: - return 0; } -//------------------------------------------------------------------------------ -/** Close a file and force cached data and directory information + +/** + * Close a file and force cached data and directory information * to be written to the storage device. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include no file is open or an I/O error. */ bool SdBaseFile::close() { @@ -102,41 +97,40 @@ bool SdBaseFile::close() { type_ = FAT_FILE_TYPE_CLOSED; return rtn; } -//------------------------------------------------------------------------------ -/** Check for contiguous file and return its raw block range. + +/** + * Check for contiguous file and return its raw block range. * * \param[out] bgnBlock the first block address for the file. * \param[out] endBlock the last block address for the file. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include file is not contiguous, file has zero length * or an I/O error occurred. */ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { // error if no blocks - if (firstCluster_ == 0) goto FAIL; + if (firstCluster_ == 0) return false; for (uint32_t c = firstCluster_; ; c++) { uint32_t next; - if (!vol_->fatGet(c, &next)) goto FAIL; + if (!vol_->fatGet(c, &next)) return false; // check for contiguous if (next != (c + 1)) { // error if not end of chain - if (!vol_->isEOC(next)) goto FAIL; + if (!vol_->isEOC(next)) return false; *bgnBlock = vol_->clusterStartBlock(firstCluster_); *endBlock = vol_->clusterStartBlock(c) + vol_->blocksPerCluster_ - 1; return true; } } - - FAIL: return false; } -//------------------------------------------------------------------------------ -/** Create and open a new contiguous file of a specified size. + +/** + * Create and open a new contiguous file of a specified size. * * \note This function only supports short DOS 8.3 names. * See open() for more information. @@ -145,20 +139,18 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { * \param[in] path A path with a valid DOS 8.3 file name. * \param[in] size The desired file size. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include \a path contains * an invalid DOS 8.3 file name, the FAT volume has not been initialized, * a file is already open, the file already exists, the root * directory is full or an I/O error. * */ -bool SdBaseFile::createContiguous(SdBaseFile* dirFile, - const char* path, uint32_t size) { +bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) { uint32_t count; // don't allow zero length file - if (size == 0) goto FAIL; - if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto FAIL; + if (size == 0) return false; + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) return false; // calculate number of clusters needed count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; @@ -166,7 +158,7 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile, // allocate clusters if (!vol_->allocContiguous(count, &firstCluster_)) { remove(); - goto FAIL; + return false; } fileSize_ = size; @@ -174,34 +166,31 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile, flags_ |= F_FILE_DIR_DIRTY; return sync(); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Return a file's directory entry. + +/** + * Return a file's directory entry. * * \param[out] dir Location for return of the file's directory entry. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::dirEntry(dir_t* dir) { dir_t* p; // make sure fields on SD are correct - if (!sync()) goto FAIL; + if (!sync()) return false; // read entry p = cacheDirEntry(SdVolume::CACHE_FOR_READ); - if (!p) goto FAIL; + if (!p) return false; // copy to caller's struct memcpy(dir, p, sizeof(dir_t)); return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Format the name field of \a dir into the 13 byte array + +/** + * Format the name field of \a dir into the 13 byte array * \a name in standard 8.3 short name format. * * \param[in] dir The directory structure containing the name. @@ -216,8 +205,9 @@ void SdBaseFile::dirName(const dir_t& dir, char* name) { } name[j] = 0; } -//------------------------------------------------------------------------------ -/** Test for the existence of a file in a directory + +/** + * Test for the existence of a file in a directory * * \param[in] name Name of the file to be tested for. * @@ -232,7 +222,7 @@ bool SdBaseFile::exists(const char* name) { SdBaseFile file; return file.open(this, name, O_READ); } -//------------------------------------------------------------------------------ + /** * Get a string from a file. * @@ -275,15 +265,15 @@ int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) { str[n] = '\0'; return n; } -//------------------------------------------------------------------------------ -/** Get a file's name + +/** + * Get a file's name * * \param[out] name An array of 13 characters for the file's name. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ -bool SdBaseFile::getFilename(char* name) { +bool SdBaseFile::getFilename(char * const name) { if (!isOpen()) return false; if (isRoot()) { @@ -299,14 +289,14 @@ bool SdBaseFile::getFilename(char* name) { dirName(*p, name); return true; } -//------------------------------------------------------------------------------ + void SdBaseFile::getpos(filepos_t* pos) { pos->position = curPosition_; pos->cluster = curCluster_; } -//------------------------------------------------------------------------------ -/** List directory contents. +/** + * List directory contents. * * \param[in] pr Print stream for list. * @@ -333,7 +323,7 @@ void SdBaseFile::ls(uint8_t flags, uint8_t indent) { } } } -//------------------------------------------------------------------------------ + // saves 32 bytes on stack for ls recursion // return 0 - EOF, 1 - normal file, or 2 - directory int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { @@ -383,41 +373,33 @@ int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { MYSERIAL.println(); return DIR_IS_FILE(&dir) ? 1 : 2; } -//------------------------------------------------------------------------------ -// format directory name field from a 8.3 name string + +// Format directory name field from a 8.3 name string bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { - uint8_t c; - uint8_t n = 7; // max index for part before dot - uint8_t i = 0; - // blank fill name and extension - while (i < 11) name[i++] = ' '; - i = 0; - while (*str != '\0' && *str != '/') { - c = *str++; - if (c == '.') { - if (n == 10) goto FAIL; // only one dot allowed - n = 10; // max index for full 8.3 name - i = 8; // place for extension + uint8_t n = 7, // Max index until a dot is found + i = 11; + while (i) name[--i] = ' '; // Set whole FILENAME.EXT to spaces + while (*str && *str != '/') { // For each character, until nul or '/' + uint8_t c = *str++; // Get char and advance + if (c == '.') { // For a dot... + if (n == 10) return false; // Already moved the max index? fail! + n = 10; // Move the max index for full 8.3 name + i = 8; // Move up to the extension place } else { - // illegal FAT characters + // Fail for illegal characters PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); - uint8_t b; - while ((b = pgm_read_byte(p++))) if (b == c) goto FAIL; - // check size and only allow ASCII printable characters - if (i > n || c < 0x21 || c == 0x7F) goto FAIL; - // only upper case allowed in 8.3 names - convert lower to upper - name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); + while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false; + if (i > n || c < 0x21 || c == 0x7F) return false; // Check size, non-printable characters + name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); // Uppercase required for 8.3 name } } - *ptr = str; - // must have a file name, extension is optional - return name[0] != ' '; - FAIL: - return false; + *ptr = str; // Set passed pointer to the end + return name[0] != ' '; // Return true if any name was set } -//------------------------------------------------------------------------------ -/** Make a new directory. + +/** + * Make a new directory. * * \param[in] parent An open SdFat instance for the directory that will contain * the new directory. @@ -426,8 +408,7 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { * * \param[in] pFlag Create missing parent directories if true. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include this file is already open, \a parent is not a * directory, \a path is invalid or already exists in \a parent. */ @@ -437,56 +418,53 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { SdBaseFile* sub = &dir1; SdBaseFile* start = parent; - if (!parent || isOpen()) goto FAIL; + if (!parent || isOpen()) return false; if (*path == '/') { while (*path == '/') path++; if (!parent->isRoot()) { - if (!dir2.openRoot(parent->vol_)) goto FAIL; + if (!dir2.openRoot(parent->vol_)) return false; parent = &dir2; } } while (1) { - if (!make83Name(path, dname, &path)) goto FAIL; + if (!make83Name(path, dname, &path)) return false; while (*path == '/') path++; if (!*path) break; if (!sub->open(parent, dname, O_READ)) { - if (!pFlag || !sub->mkdir(parent, dname)) { - goto FAIL; - } + if (!pFlag || !sub->mkdir(parent, dname)) + return false; } if (parent != start) parent->close(); parent = sub; sub = parent != &dir1 ? &dir1 : &dir2; } return mkdir(parent, dname); - FAIL: - return false; } -//------------------------------------------------------------------------------ + bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { uint32_t block; dir_t d; dir_t* p; - if (!parent->isDir()) goto FAIL; + if (!parent->isDir()) return false; // create a normal file - if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto FAIL; + if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) return false; // convert file to directory flags_ = O_READ; type_ = FAT_FILE_TYPE_SUBDIR; // allocate and zero first cluster - if (!addDirCluster())goto FAIL; + if (!addDirCluster()) return false; // force entry to SD - if (!sync()) goto FAIL; + if (!sync()) return false; // cache entry - should already be in cache due to sync() call p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!p) goto FAIL; + if (!p) return false; // change directory entry attribute p->attributes = DIR_ATT_DIRECTORY; @@ -498,7 +476,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { // cache block for '.' and '..' block = vol_->clusterStartBlock(firstCluster_); - if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL; + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false; // copy '.' to block memcpy(&vol_->cache()->dir[0], &d, sizeof(d)); @@ -518,25 +496,24 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { // write first block return vol_->cacheFlush(); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Open a file in the current working directory. + +/** + * Open a file in the current working directory. * * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. * * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::open(const char* path, uint8_t oflag) { return open(cwd_, path, oflag); } -//------------------------------------------------------------------------------ -/** Open a file or directory by name. + +/** + * Open a file or directory by name. * * \param[in] dirFile An open SdFat instance for the directory containing the * file to be opened. @@ -580,8 +557,7 @@ bool SdBaseFile::open(const char* path, uint8_t oflag) { * \note Directory files must be opened read only. Write and truncation is * not allowed for directory files. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include this file is already open, \a dirFile is not * a directory, \a path is invalid, the file does not exist * or can't be opened in the access mode specified by oflag. @@ -589,40 +565,33 @@ bool SdBaseFile::open(const char* path, uint8_t oflag) { bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) { uint8_t dname[11]; SdBaseFile dir1, dir2; - SdBaseFile* parent = dirFile; - SdBaseFile* sub = &dir1; + SdBaseFile *parent = dirFile, *sub = &dir1; - if (!dirFile) goto FAIL; + if (!dirFile || isOpen()) return false; - // error if already open - if (isOpen()) goto FAIL; - - if (*path == '/') { - while (*path == '/') path++; - if (!dirFile->isRoot()) { - if (!dir2.openRoot(dirFile->vol_)) goto FAIL; - parent = &dir2; + if (*path == '/') { // Path starts with '/' + if (!dirFile->isRoot()) { // Is the passed dirFile the root? + if (!dir2.openRoot(dirFile->vol_)) return false; // Get the root in dir2, if possible + parent = &dir2; // Change 'parent' to point at the root dir } + while (*path == '/') path++; // Skip all leading slashes } - while (1) { - if (!make83Name(path, dname, &path)) goto FAIL; + + for (;;) { + if (!make83Name(path, dname, &path)) return false; while (*path == '/') path++; if (!*path) break; - if (!sub->open(parent, dname, O_READ)) goto FAIL; + if (!sub->open(parent, dname, O_READ)) return false; if (parent != dirFile) parent->close(); parent = sub; sub = parent != &dir1 ? &dir1 : &dir2; } return open(parent, dname, oflag); - FAIL: - return false; } -//------------------------------------------------------------------------------ + // open with filename in dname -bool SdBaseFile::open(SdBaseFile* dirFile, - const uint8_t dname[11], uint8_t oflag) { - bool emptyFound = false; - bool fileFound = false; +bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag) { + bool emptyFound = false, fileFound = false; uint8_t index; dir_t* p; @@ -634,7 +603,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, while (dirFile->curPosition_ < dirFile->fileSize_) { index = 0XF & (dirFile->curPosition_ >> 5); p = dirFile->readDirCache(); - if (!p) goto FAIL; + if (!p) return false; if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { // remember first empty slot @@ -653,21 +622,21 @@ bool SdBaseFile::open(SdBaseFile* dirFile, } if (fileFound) { // don't open existing file if O_EXCL - if (oflag & O_EXCL) goto FAIL; + if (oflag & O_EXCL) return false; } else { // don't create unless O_CREAT and O_WRITE - if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto FAIL; + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) return false; if (emptyFound) { index = dirIndex_; p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!p) goto FAIL; + if (!p) return false; } else { - if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto FAIL; + if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) return false; // add and zero cluster for dirFile - first cluster is in cache for write - if (!dirFile->addDirCluster()) goto FAIL; + if (!dirFile->addDirCluster()) return false; // use first entry in cluster p = dirFile->vol_->cache()->dir; @@ -692,15 +661,14 @@ bool SdBaseFile::open(SdBaseFile* dirFile, p->lastWriteTime = p->creationTime; // write entry to SD - if (!dirFile->vol_->cacheFlush()) goto FAIL; + if (!dirFile->vol_->cacheFlush()) return false; } // open entry in cache return openCachedEntry(index, oflag); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Open a file by index. + +/** + * Open a file by index. * * \param[in] dirFile An open SdFat instance for the directory. * @@ -719,29 +687,27 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { vol_ = dirFile->vol_; // error if already open - if (isOpen() || !dirFile) goto FAIL; + if (isOpen() || !dirFile) return false; // don't open existing file if O_EXCL - user call error - if (oflag & O_EXCL) goto FAIL; + if (oflag & O_EXCL) return false; // seek to location of entry - if (!dirFile->seekSet(32 * index)) goto FAIL; + if (!dirFile->seekSet(32 * index)) return false; // read entry into cache p = dirFile->readDirCache(); - if (!p) goto FAIL; + if (!p) return false; // error if empty slot or '.' or '..' if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { - goto FAIL; + return false; } // open cached entry return openCachedEntry(index & 0XF, oflag); - FAIL: - return false; } -//------------------------------------------------------------------------------ + // open a cached directory entry. Assumes vol_ is initialized bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { // location of entry in cache @@ -768,9 +734,9 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { if (!vol_->chainSize(firstCluster_, &fileSize_)) goto FAIL; type_ = FAT_FILE_TYPE_SUBDIR; } - else { + else goto FAIL; - } + // save open flags for read/write flags_ = oflag & F_OFLAG; @@ -779,12 +745,14 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { curPosition_ = 0; if ((oflag & O_TRUNC) && !truncate(0)) return false; return oflag & O_AT_END ? seekEnd(0) : true; + FAIL: type_ = FAT_FILE_TYPE_CLOSED; return false; } -//------------------------------------------------------------------------------ -/** Open the next file or subdirectory in a directory. + +/** + * Open the next file or subdirectory in a directory. * * \param[in] dirFile An open SdFat instance for the directory containing the * file to be opened. @@ -799,10 +767,10 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { dir_t* p; uint8_t index; - if (!dirFile) goto FAIL; + if (!dirFile) return false; // error if already open - if (isOpen()) goto FAIL; + if (isOpen()) return false; vol_ = dirFile->vol_; @@ -811,10 +779,10 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { // read entry into cache p = dirFile->readDirCache(); - if (!p) goto FAIL; + if (!p) return false; // done if last entry - if (p->name[0] == DIR_NAME_FREE) goto FAIL; + if (p->name[0] == DIR_NAME_FREE) return false; // skip empty slot or '.' or '..' if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { @@ -825,16 +793,16 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { return openCachedEntry(index, oflag); } } - FAIL: return false; } -//------------------------------------------------------------------------------ -/** Open a directory's parent directory. + +#if 0 +/** + * Open a directory's parent directory. * * \param[in] dir Parent of this directory will be opened. Must not be root. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::openParent(SdBaseFile* dir) { dir_t entry; @@ -844,14 +812,14 @@ bool SdBaseFile::openParent(SdBaseFile* dir) { uint32_t cluster; uint32_t lbn; // error if already open or dir is root or dir is not a directory - if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto FAIL; + if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) return false; vol_ = dir->vol_; // position to '..' - if (!dir->seekSet(32)) goto FAIL; + if (!dir->seekSet(32)) return false; // read '..' entry - if (dir->read(&entry, sizeof(entry)) != 32) goto FAIL; + if (dir->read(&entry, sizeof(entry)) != 32) return false; // verify it is '..' - if (entry.name[0] != '.' || entry.name[1] != '.') goto FAIL; + if (entry.name[0] != '.' || entry.name[1] != '.') return false; // start cluster for '..' cluster = entry.firstClusterLow; cluster |= (uint32_t)entry.firstClusterHigh << 16; @@ -859,43 +827,42 @@ bool SdBaseFile::openParent(SdBaseFile* dir) { // start block for '..' lbn = vol_->clusterStartBlock(cluster); // first block of parent dir - if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) { - goto FAIL; - } + if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) return false; + p = &vol_->cacheBuffer_.dir[1]; // verify name for '../..' - if (p->name[0] != '.' || p->name[1] != '.') goto FAIL; + if (p->name[0] != '.' || p->name[1] != '.') return false; // '..' is pointer to first cluster of parent. open '../..' to find parent if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { - if (!file.openRoot(dir->volume())) goto FAIL; - } - else if (!file.openCachedEntry(1, O_READ)) { - goto FAIL; + if (!file.openRoot(dir->volume())) return false; } + else if (!file.openCachedEntry(1, O_READ)) + return false; + // search for parent in '../..' do { - if (file.readDir(&entry, NULL) != 32) goto FAIL; + if (file.readDir(&entry, NULL) != 32) return false; c = entry.firstClusterLow; c |= (uint32_t)entry.firstClusterHigh << 16; } while (c != cluster); + // open parent return open(&file, file.curPosition() / 32 - 1, O_READ); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Open a volume's root directory. +#endif + +/** + * Open a volume's root directory. * * \param[in] vol The FAT volume containing the root directory to be opened. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include the file is already open, the FAT volume has * not been initialized or it a FAT12 volume. */ bool SdBaseFile::openRoot(SdVolume* vol) { // error if file is already open - if (isOpen()) goto FAIL; + if (isOpen()) return false; if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { type_ = FAT_FILE_TYPE_ROOT_FIXED; @@ -905,29 +872,25 @@ bool SdBaseFile::openRoot(SdVolume* vol) { else if (vol->fatType() == 32) { type_ = FAT_FILE_TYPE_ROOT32; firstCluster_ = vol->rootDirStart(); - if (!vol->chainSize(firstCluster_, &fileSize_)) goto FAIL; + if (!vol->chainSize(firstCluster_, &fileSize_)) return false; } - else { - // volume is not initialized, invalid, or FAT12 without support + else // volume is not initialized, invalid, or FAT12 without support return false; - } + vol_ = vol; // read only flags_ = O_READ; // set to start of file - curCluster_ = 0; - curPosition_ = 0; + curCluster_ = curPosition_ = 0; // root has no directory entry - dirBlock_ = 0; - dirIndex_ = 0; + dirBlock_ = dirIndex_ = 0; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Return the next available byte without consuming it. + +/** + * Return the next available byte without consuming it. * * \return The byte if no error and not at eof else -1; */ @@ -939,50 +902,24 @@ int SdBaseFile::peek() { return c; } -//------------------------------------------------------------------------------ -/** %Print the name field of a directory entry in 8.3 format. - * \param[in] pr Print stream for output. - * \param[in] dir The directory structure containing the name. - * \param[in] width Blank fill name if length is less than \a width. - * \param[in] printSlash Print '/' after directory names if true. - */ -void SdBaseFile::printDirName(const dir_t& dir, - uint8_t width, bool printSlash) { - uint8_t w = 0; - for (uint8_t i = 0; i < 11; i++) { - if (dir.name[i] == ' ')continue; - if (i == 8) { - MYSERIAL.write('.'); - w++; - } - MYSERIAL.write(dir.name[i]); - w++; - } - if (DIR_IS_SUBDIR(&dir) && printSlash) { - MYSERIAL.write('/'); - w++; - } - while (w < width) { - MYSERIAL.write(' '); - w++; - } -} -//------------------------------------------------------------------------------ + // print uint8_t with width 2 static void print2u(uint8_t v) { if (v < 10) MYSERIAL.write('0'); MYSERIAL.print(v, DEC); } -//------------------------------------------------------------------------------ -/** %Print a directory date field to Serial. + +/** + * %Print a directory date field to Serial. * * Format is yyyy-mm-dd. * * \param[in] fatDate The date field from a directory entry. */ -//------------------------------------------------------------------------------ -/** %Print a directory date field. + +/** + * %Print a directory date field. * * Format is yyyy-mm-dd. * @@ -997,8 +934,9 @@ void SdBaseFile::printFatDate(uint16_t fatDate) { print2u(FAT_DAY(fatDate)); } -//------------------------------------------------------------------------------ -/** %Print a directory time field. + +/** + * %Print a directory time field. * * Format is hh:mm:ss. * @@ -1012,11 +950,11 @@ void SdBaseFile::printFatTime(uint16_t fatTime) { MYSERIAL.write(':'); print2u(FAT_SECOND(fatTime)); } -//------------------------------------------------------------------------------ -/** Print a file's name to Serial + +/** + * Print a file's name to Serial * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::printName() { char name[FILENAME_LENGTH]; @@ -1024,8 +962,9 @@ bool SdBaseFile::printName() { MYSERIAL.print(name); return true; } -//------------------------------------------------------------------------------ -/** Read the next byte from a file. + +/** + * Read the next byte from a file. * * \return For success read returns the next byte in the file as an int. * If an error occurs or end of file is reached -1 is returned. @@ -1034,8 +973,9 @@ int16_t SdBaseFile::read() { uint8_t b; return read(&b, 1) == 1 ? b : -1; } -//------------------------------------------------------------------------------ -/** Read data from a file starting at the current position. + +/** + * Read data from a file starting at the current position. * * \param[out] buf Pointer to the location that will receive the data. * @@ -1050,12 +990,11 @@ int16_t SdBaseFile::read() { */ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { uint8_t* dst = reinterpret_cast(buf); - uint16_t offset; - uint16_t toRead; + uint16_t offset, toRead; uint32_t block; // raw device block number // error if not open or write only - if (!isOpen() || !(flags_ & O_READ)) goto FAIL; + if (!isOpen() || !(flags_ & O_READ)) return -1; // max bytes left in file NOMORE(nbyte, fileSize_ - curPosition_); @@ -1071,14 +1010,10 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); if (offset == 0 && blockOfCluster == 0) { // start of new cluster - if (curPosition_ == 0) { - // use first cluster in file - curCluster_ = firstCluster_; - } - else { - // get next cluster from FAT - if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL; - } + if (curPosition_ == 0) + curCluster_ = firstCluster_; // use first cluster in file + else if (!vol_->fatGet(curCluster_, &curCluster_)) // get next cluster from FAT + return -1; } block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; } @@ -1089,11 +1024,11 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { // no buffering needed if n == 512 if (n == 512 && block != vol_->cacheBlockNumber()) { - if (!vol_->readBlock(block, dst)) goto FAIL; + if (!vol_->readBlock(block, dst)) return -1; } else { // read block to cache and copy data to caller - if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL; + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1; uint8_t* src = vol_->cache()->data + offset; memcpy(dst, src, n); } @@ -1102,8 +1037,6 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { toRead -= n; } return nbyte; - FAIL: - return -1; } /** @@ -1128,7 +1061,7 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { while (1) { n = read(dir, sizeof(dir_t)); - if (n != sizeof(dir_t)) return n == 0 ? 0 : -1; + if (n != sizeof(dir_t)) return n ? -1 : 0; // last entry if DIR_NAME_FREE if (dir->name[0] == DIR_NAME_FREE) return 0; @@ -1141,13 +1074,16 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { if (longFilename != NULL && DIR_IS_LONG_NAME(dir)) { vfat_t* VFAT = (vfat_t*)dir; // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0 - if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) { - // TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table. - n = ((VFAT->sequenceNumber & 0x1F) - 1) * (FILENAME_LENGTH); - for (uint8_t i = 0; i < FILENAME_LENGTH; i++) - longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11]; - // If this VFAT entry is the last one, add a NUL terminator at the end of the string - if (VFAT->sequenceNumber & 0x40) longFilename[n + FILENAME_LENGTH] = '\0'; + if (VFAT->firstClusterLow == 0) { + const uint8_t seq = VFAT->sequenceNumber & 0x1F; + if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) { + // TODO: Store the filename checksum to verify if a long-filename-unaware system modified the file table. + n = (seq - 1) * (FILENAME_LENGTH); + for (uint8_t i = 0; i < FILENAME_LENGTH; i++) + longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11]; + // If this VFAT entry is the last one, add a NUL terminator at the end of the string + if (VFAT->sequenceNumber & 0x40) longFilename[n + FILENAME_LENGTH] = '\0'; + } } } // Return if normal file or subdirectory @@ -1155,30 +1091,29 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { } } -//------------------------------------------------------------------------------ + // Read next directory entry into the cache // Assumes file is correctly positioned dir_t* SdBaseFile::readDirCache() { uint8_t i; // error if not directory - if (!isDir()) goto FAIL; + if (!isDir()) return 0; // index of entry in cache i = (curPosition_ >> 5) & 0XF; // use read to locate and cache block - if (read() < 0) goto FAIL; + if (read() < 0) return 0; // advance to next entry curPosition_ += 31; // return pointer to entry return vol_->cache()->dir + i; - FAIL: - return 0; } -//------------------------------------------------------------------------------ -/** Remove a file. + +/** + * Remove a file. * * The directory entry and all data for the file are deleted. * @@ -1186,19 +1121,18 @@ dir_t* SdBaseFile::readDirCache() { * file that has a long name. For example if a file has the long name * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include the file read-only, is a directory, * or an I/O error occurred. */ bool SdBaseFile::remove() { dir_t* d; // free any clusters - will fail if read-only or directory - if (!truncate(0)) goto FAIL; + if (!truncate(0)) return false; // cache directory entry d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; + if (!d) return false; // mark entry deleted d->name[0] = DIR_NAME_DELETED; @@ -1209,11 +1143,10 @@ bool SdBaseFile::remove() { // write entry to SD return vol_->cacheFlush(); return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Remove a file. + +/** + * Remove a file. * * The directory entry and all data for the file are deleted. * @@ -1224,28 +1157,23 @@ bool SdBaseFile::remove() { * file that has a long name. For example if a file has the long name * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include the file is a directory, is read only, * \a dirFile is not a directory, \a path is not found * or an I/O error occurred. */ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { SdBaseFile file; - if (!file.open(dirFile, path, O_WRITE)) goto FAIL; - return file.remove(); - FAIL: - // can't set iostate - static function - return false; + return file.open(dirFile, path, O_WRITE) ? file.remove() : false; } -//------------------------------------------------------------------------------ -/** Rename a file or subdirectory. + +/** + * Rename a file or subdirectory. * * \param[in] dirFile Directory for the new path. * \param[in] newPath New path name for the file/directory. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include \a dirFile is not open or is not a directory * file, newPath is invalid or already exists, or an I/O error occurs. */ @@ -1256,15 +1184,15 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { dir_t* d; // must be an open file or subdirectory - if (!(isFile() || isSubDir())) goto FAIL; + if (!(isFile() || isSubDir())) return false; // can't move file - if (vol_ != dirFile->vol_) goto FAIL; + if (vol_ != dirFile->vol_) return false; // sync() and cache directory entry sync(); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; + if (!d) return false; // save directory entry memcpy(&entry, d, sizeof(entry)); @@ -1295,7 +1223,7 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { // cache new directory entry d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; + if (!d) return false; // copy all but name field to new directory entry memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); @@ -1304,31 +1232,30 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { if (dirCluster) { // get new dot dot uint32_t block = vol_->clusterStartBlock(dirCluster); - if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL; + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return false; memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry)); // free unused cluster - if (!vol_->freeChain(dirCluster)) goto FAIL; + if (!vol_->freeChain(dirCluster)) return false; // store new dot dot block = vol_->clusterStartBlock(firstCluster_); - if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL; + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false; memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry)); } return vol_->cacheFlush(); restore: - d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; - // restore entry - d->name[0] = entry.name[0]; - vol_->cacheFlush(); - - FAIL: + if ((d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE))) { + // restore entry + d->name[0] = entry.name[0]; + vol_->cacheFlush(); + } return false; } -//------------------------------------------------------------------------------ -/** Remove a directory file. + +/** + * Remove a directory file. * * The directory file will be removed only if it is empty and is not the * root directory. rmdir() follows DOS and Windows and ignores the @@ -1338,37 +1265,35 @@ restore: * directory that has a long name. For example if a directory has the * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include the file is not a directory, is the root * directory, is not empty, or an I/O error occurred. */ bool SdBaseFile::rmdir() { // must be open subdirectory - if (!isSubDir()) goto FAIL; + if (!isSubDir()) return false; rewind(); // make sure directory is empty while (curPosition_ < fileSize_) { dir_t* p = readDirCache(); - if (!p) goto FAIL; + if (!p) return false; // done if past last used entry if (p->name[0] == DIR_NAME_FREE) break; // skip empty slot, '.' or '..' if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; // error not empty - if (DIR_IS_FILE_OR_SUBDIR(p)) goto FAIL; + if (DIR_IS_FILE_OR_SUBDIR(p)) return false; } // convert empty directory to normal file for remove type_ = FAT_FILE_TYPE_NORMAL; flags_ |= O_WRITE; return remove(); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Recursively delete a directory and all contained files. + +/** + * Recursively delete a directory and all contained files. * * This is like the Unix/Linux 'rm -rf *' if called with the root directory * hence the name. @@ -1380,11 +1305,10 @@ bool SdBaseFile::rmdir() { * \note This function should not be used to delete the 8.3 version of * a directory that has a long name. See remove() and rmdir(). * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::rmRfStar() { - uint16_t index; + uint32_t index; SdBaseFile f; rewind(); while (curPosition_ < fileSize_) { @@ -1392,7 +1316,7 @@ bool SdBaseFile::rmRfStar() { index = curPosition_ / 32; dir_t* p = readDirCache(); - if (!p) goto FAIL; + if (!p) return false; // done if past last entry if (p->name[0] == DIR_NAME_FREE) break; @@ -1403,31 +1327,30 @@ bool SdBaseFile::rmRfStar() { // skip if part of long file name or volume label in root if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; - if (!f.open(this, index, O_READ)) goto FAIL; + if (!f.open(this, index, O_READ)) return false; if (f.isSubDir()) { // recursively delete - if (!f.rmRfStar()) goto FAIL; + if (!f.rmRfStar()) return false; } else { // ignore read-only f.flags_ |= O_WRITE; - if (!f.remove()) goto FAIL; + if (!f.remove()) return false; } // position to next entry if required if (curPosition_ != (32 * (index + 1))) { - if (!seekSet(32 * (index + 1))) goto FAIL; + if (!seekSet(32 * (index + 1))) return false; } } // don't try to delete root if (!isRoot()) { - if (!rmdir()) goto FAIL; + if (!rmdir()) return false; } return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Create a file object and open it in the current working directory. + +/** + * Create a file object and open it in the current working directory. * * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. * @@ -1439,64 +1362,54 @@ SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { writeError = false; open(path, oflag); } -//------------------------------------------------------------------------------ -/** Sets a file's position. + +/** + * Sets a file's position. * * \param[in] pos The new position in bytes from the beginning of the file. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ -bool SdBaseFile::seekSet(uint32_t pos) { - uint32_t nCur; - uint32_t nNew; +bool SdBaseFile::seekSet(const uint32_t pos) { + uint32_t nCur, nNew; // error if file not open or seek past end of file - if (!isOpen() || pos > fileSize_) goto FAIL; + if (!isOpen() || pos > fileSize_) return false; if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { curPosition_ = pos; - goto done; + return true; } if (pos == 0) { - // set position to start of file - curCluster_ = 0; - curPosition_ = 0; - goto done; + curCluster_ = curPosition_ = 0; // set position to start of file + return true; } + // calculate cluster index for cur and new position nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); - if (nNew < nCur || curPosition_ == 0) { - // must follow chain from first cluster - curCluster_ = firstCluster_; - } - else { - // advance from curPosition - nNew -= nCur; - } - while (nNew--) { - if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL; - } + if (nNew < nCur || curPosition_ == 0) + curCluster_ = firstCluster_; // must follow chain from first cluster + else + nNew -= nCur; // advance from curPosition + + while (nNew--) + if (!vol_->fatGet(curCluster_, &curCluster_)) return false; + curPosition_ = pos; - -done: return true; - - FAIL: - return false; } -//------------------------------------------------------------------------------ + void SdBaseFile::setpos(filepos_t* pos) { curPosition_ = pos->position; curCluster_ = pos->cluster; } -//------------------------------------------------------------------------------ -/** The sync() call causes all modified data and directory fields + +/** + * The sync() call causes all modified data and directory fields * to be written to the storage device. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include a call to sync() before a file has been * opened or an I/O error. */ @@ -1530,8 +1443,9 @@ bool SdBaseFile::sync() { writeError = true; return false; } -//------------------------------------------------------------------------------ -/** Copy a file's timestamps + +/** + * Copy a file's timestamps * * \param[in] file File to copy timestamps from. * @@ -1539,21 +1453,20 @@ bool SdBaseFile::sync() { * Modify and access timestamps may be overwritten if a date time callback * function has been set by dateTimeCallback(). * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::timestamp(SdBaseFile* file) { dir_t* d; dir_t dir; // get timestamps - if (!file->dirEntry(&dir)) goto FAIL; + if (!file->dirEntry(&dir)) return false; // update directory fields - if (!sync()) goto FAIL; + if (!sync()) return false; d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; + if (!d) return false; // copy timestamps d->lastAccessDate = dir.lastAccessDate; @@ -1565,12 +1478,10 @@ bool SdBaseFile::timestamp(SdBaseFile* file) { // write back entry return vol_->cacheFlush(); - - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Set a file's timestamps in its directory entry. + +/** + * Set a file's timestamps in its directory entry. * * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive * OR of flags from the following list @@ -1600,13 +1511,11 @@ bool SdBaseFile::timestamp(SdBaseFile* file) { * Modify and access timestamps may be overwritten if a date time callback * function has been set by dateTimeCallback(). * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. */ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { - uint16_t dirDate; - uint16_t dirTime; + uint16_t dirDate, dirTime; dir_t* d; if (!isOpen() @@ -1619,13 +1528,13 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, || hour > 23 || minute > 59 || second > 59) { - goto FAIL; + return false; } // update directory entry - if (!sync()) goto FAIL; + if (!sync()) return false; d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); - if (!d) goto FAIL; + if (!d) return false; dirDate = FAT_DATE(year, month, day); dirTime = FAT_TIME(hour, minute, second); @@ -1643,28 +1552,26 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, d->lastWriteTime = dirTime; } return vol_->cacheFlush(); - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Truncate a file to a specified length. The current file position + +/** + * Truncate a file to a specified length. The current file position * will be maintained if it is less than or equal to \a length otherwise * it will be set to end of file. * * \param[in] length The desired length for the file. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. + * \return true for success, false for failure. * Reasons for failure include file is read only, file is a directory, * \a length is greater than the current file size or an I/O error occurs. */ bool SdBaseFile::truncate(uint32_t length) { uint32_t newPos; // error if not a normal file or read-only - if (!isFile() || !(flags_ & O_WRITE)) goto FAIL; + if (!isFile() || !(flags_ & O_WRITE)) return false; // error if length is greater than current size - if (length > fileSize_) goto FAIL; + if (length > fileSize_) return false; // fileSize and length are zero - nothing to do if (fileSize_ == 0) return true; @@ -1673,23 +1580,23 @@ bool SdBaseFile::truncate(uint32_t length) { newPos = curPosition_ > length ? length : curPosition_; // position to last cluster in truncated file - if (!seekSet(length)) goto FAIL; + if (!seekSet(length)) return false; if (length == 0) { // free all clusters - if (!vol_->freeChain(firstCluster_)) goto FAIL; + if (!vol_->freeChain(firstCluster_)) return false; firstCluster_ = 0; } else { uint32_t toFree; - if (!vol_->fatGet(curCluster_, &toFree)) goto FAIL; + if (!vol_->fatGet(curCluster_, &toFree)) return false; if (!vol_->isEOC(toFree)) { // free extra clusters - if (!vol_->freeChain(toFree)) goto FAIL; + if (!vol_->freeChain(toFree)) return false; // current cluster is end of chain - if (!vol_->fatPutEOC(curCluster_)) goto FAIL; + if (!vol_->fatPutEOC(curCluster_)) return false; } } fileSize_ = length; @@ -1697,16 +1604,14 @@ bool SdBaseFile::truncate(uint32_t length) { // need to update directory entry flags_ |= F_FILE_DIR_DIRTY; - if (!sync()) goto FAIL; + if (!sync()) return false; // set file to correct position return seekSet(newPos); - - FAIL: - return false; } -//------------------------------------------------------------------------------ -/** Write data to an open file. + +/** + * Write data to an open file. * * \note Data is moved to the cache but may not be written to the * storage device until sync() is called. @@ -1816,11 +1721,9 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) { writeError = true; return -1; } -//------------------------------------------------------------------------------ -// suppress cpplint warnings with NOLINT comment -#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) - void (*SdBaseFile::oldDateTime_)(uint16_t &date, uint16_t &time) = 0; // NOLINT -#endif // ALLOW_DEPRECATED_FUNCTIONS - +#if ALLOW_DEPRECATED_FUNCTIONS + void (*SdBaseFile::oldDateTime_)(uint16_t &date, uint16_t &time) = 0; #endif + +#endif // SDSUPPORT diff --git a/Marlin/SdBaseFile.h b/Marlin/SdBaseFile.h index 02daa7b7f2..425c65f9b2 100644 --- a/Marlin/SdBaseFile.h +++ b/Marlin/SdBaseFile.h @@ -20,208 +20,196 @@ * */ +/** + * \file + * \brief SdBaseFile class + */ + /** * Arduino SdFat Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) +#ifndef _SDBASEFILE_H_ +#define _SDBASEFILE_H_ -#ifndef SdBaseFile_h -#define SdBaseFile_h -/** - * \file - * \brief SdBaseFile class - */ -#include "Marlin.h" #include "SdFatConfig.h" #include "SdVolume.h" -//------------------------------------------------------------------------------ + /** * \struct filepos_t * \brief internal type for istream * do not use in user apps */ struct filepos_t { - /** stream position */ - uint32_t position; - /** cluster for position */ - uint32_t cluster; + uint32_t position; // stream byte position + uint32_t cluster; // cluster of position filepos_t() : position(0), cluster(0) {} }; // use the gnu style oflag in open() -/** open() oflag for reading */ -uint8_t const O_READ = 0x01; -/** open() oflag - same as O_IN */ -uint8_t const O_RDONLY = O_READ; -/** open() oflag for write */ -uint8_t const O_WRITE = 0x02; -/** open() oflag - same as O_WRITE */ -uint8_t const O_WRONLY = O_WRITE; -/** open() oflag for reading and writing */ -uint8_t const O_RDWR = (O_READ | O_WRITE); -/** open() oflag mask for access modes */ -uint8_t const O_ACCMODE = (O_READ | O_WRITE); -/** The file offset shall be set to the end of the file prior to each write. */ -uint8_t const O_APPEND = 0x04; -/** synchronous writes - call sync() after each write */ -uint8_t const O_SYNC = 0x08; -/** truncate the file to zero length */ -uint8_t const O_TRUNC = 0x10; -/** set the initial position at the end of the file */ -uint8_t const O_AT_END = 0x20; -/** create the file if nonexistent */ -uint8_t const O_CREAT = 0x40; -/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ -uint8_t const O_EXCL = 0x80; +uint8_t const O_READ = 0x01, // open() oflag for reading + O_RDONLY = O_READ, // open() oflag - same as O_IN + O_WRITE = 0x02, // open() oflag for write + O_WRONLY = O_WRITE, // open() oflag - same as O_WRITE + O_RDWR = (O_READ | O_WRITE), // open() oflag for reading and writing + O_ACCMODE = (O_READ | O_WRITE), // open() oflag mask for access modes + O_APPEND = 0x04, // The file offset shall be set to the end of the file prior to each write. + O_SYNC = 0x08, // Synchronous writes - call sync() after each write + O_TRUNC = 0x10, // Truncate the file to zero length + O_AT_END = 0x20, // Set the initial position at the end of the file + O_CREAT = 0x40, // Create the file if nonexistent + O_EXCL = 0x80; // If O_CREAT and O_EXCL are set, open() shall fail if the file exists // SdBaseFile class static and const definitions + // flags for ls() -/** ls() flag to print modify date */ -uint8_t const LS_DATE = 1; -/** ls() flag to print file size */ -uint8_t const LS_SIZE = 2; -/** ls() flag for recursive list of subdirectories */ -uint8_t const LS_R = 4; +uint8_t const LS_DATE = 1, // ls() flag to print modify date + LS_SIZE = 2, // ls() flag to print file size + LS_R = 4; // ls() flag for recursive list of subdirectories // flags for timestamp -/** set the file's last access date */ -uint8_t const T_ACCESS = 1; -/** set the file's creation date and time */ -uint8_t const T_CREATE = 2; -/** Set the file's write date and time */ -uint8_t const T_WRITE = 4; -// values for type_ -/** This file has not been opened. */ -uint8_t const FAT_FILE_TYPE_CLOSED = 0; -/** A normal file */ -uint8_t const FAT_FILE_TYPE_NORMAL = 1; -/** A FAT12 or FAT16 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2; -/** A FAT32 root directory */ -uint8_t const FAT_FILE_TYPE_ROOT32 = 3; -/** A subdirectory file*/ -uint8_t const FAT_FILE_TYPE_SUBDIR = 4; -/** Test value for directory type */ -uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; +uint8_t const T_ACCESS = 1, // Set the file's last access date + T_CREATE = 2, // Set the file's creation date and time + T_WRITE = 4; // Set the file's write date and time -/** date field for FAT directory entry +// values for type_ +uint8_t const FAT_FILE_TYPE_CLOSED = 0, // This file has not been opened. + FAT_FILE_TYPE_NORMAL = 1, // A normal file + FAT_FILE_TYPE_ROOT_FIXED = 2, // A FAT12 or FAT16 root directory + FAT_FILE_TYPE_ROOT32 = 3, // A FAT32 root directory + FAT_FILE_TYPE_SUBDIR = 4, // A subdirectory file + FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; // Test value for directory type + +/** + * date field for FAT directory entry * \param[in] year [1980,2107] * \param[in] month [1,12] * \param[in] day [1,31] * * \return Packed date for dir_t entry. */ -static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { - return (year - 1980) << 9 | month << 5 | day; -} -/** year part of FAT directory date field +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { return (year - 1980) << 9 | month << 5 | day; } + +/** + * year part of FAT directory date field * \param[in] fatDate Date in packed dir format. * * \return Extracted year [1980,2107] */ -static inline uint16_t FAT_YEAR(uint16_t fatDate) { - return 1980 + (fatDate >> 9); -} -/** month part of FAT directory date field +static inline uint16_t FAT_YEAR(uint16_t fatDate) { return 1980 + (fatDate >> 9); } + +/** + * month part of FAT directory date field * \param[in] fatDate Date in packed dir format. * * \return Extracted month [1,12] */ -static inline uint8_t FAT_MONTH(uint16_t fatDate) { - return (fatDate >> 5) & 0XF; -} -/** day part of FAT directory date field +static inline uint8_t FAT_MONTH(uint16_t fatDate) { return (fatDate >> 5) & 0XF; } + +/** + * day part of FAT directory date field * \param[in] fatDate Date in packed dir format. * * \return Extracted day [1,31] */ -static inline uint8_t FAT_DAY(uint16_t fatDate) { - return fatDate & 0x1F; -} -/** time field for FAT directory entry +static inline uint8_t FAT_DAY(uint16_t fatDate) { return fatDate & 0x1F; } + +/** + * time field for FAT directory entry * \param[in] hour [0,23] * \param[in] minute [0,59] * \param[in] second [0,59] * * \return Packed time for dir_t entry. */ -static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { - return hour << 11 | minute << 5 | second >> 1; -} -/** hour part of FAT directory time field +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { return hour << 11 | minute << 5 | second >> 1; } + +/** + * hour part of FAT directory time field * \param[in] fatTime Time in packed dir format. * * \return Extracted hour [0,23] */ -static inline uint8_t FAT_HOUR(uint16_t fatTime) { - return fatTime >> 11; -} -/** minute part of FAT directory time field +static inline uint8_t FAT_HOUR(uint16_t fatTime) { return fatTime >> 11; } + +/** + * minute part of FAT directory time field * \param[in] fatTime Time in packed dir format. * * \return Extracted minute [0,59] */ -static inline uint8_t FAT_MINUTE(uint16_t fatTime) { - return (fatTime >> 5) & 0x3F; -} -/** second part of FAT directory time field +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { return (fatTime >> 5) & 0x3F; } + +/** + * second part of FAT directory time field * Note second/2 is stored in packed time. * * \param[in] fatTime Time in packed dir format. * * \return Extracted second [0,58] */ -static inline uint8_t FAT_SECOND(uint16_t fatTime) { - return 2 * (fatTime & 0x1F); -} -/** Default date for file timestamps is 1 Jan 2000 */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { return 2 * (fatTime & 0x1F); } + +// Default date for file timestamps is 1 Jan 2000 uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; -/** Default time for file timestamp is 1 am */ +// Default time for file timestamp is 1 am uint16_t const FAT_DEFAULT_TIME = (1 << 11); -//------------------------------------------------------------------------------ + /** * \class SdBaseFile * \brief Base class for SdFile with Print and C++ streams. */ class SdBaseFile { public: - /** Create an instance. */ SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} SdBaseFile(const char* path, uint8_t oflag); - ~SdBaseFile() {if (isOpen()) close();} + ~SdBaseFile() { if (isOpen()) close(); } + /** * writeError is set to true if an error occurs during a write(). * Set writeError to false before calling print() and/or write() and check * for true after calls to print() and/or write(). */ bool writeError; - //---------------------------------------------------------------------------- + // helpers for stream classes - /** get position for streams + + /** + * get position for streams * \param[out] pos struct to receive position */ void getpos(filepos_t* pos); - /** set position for streams + + /** + * set position for streams * \param[out] pos struct with value for new position */ void setpos(filepos_t* pos); - //---------------------------------------------------------------------------- + bool close(); bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); bool createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size); - /** \return The current cluster number for a file or directory. */ - uint32_t curCluster() const {return curCluster_;} - /** \return The current position for a file or directory. */ - uint32_t curPosition() const {return curPosition_;} - /** \return Current working directory */ - static SdBaseFile* cwd() {return cwd_;} - /** Set the date/time callback function + /** + * \return The current cluster number for a file or directory. + */ + uint32_t curCluster() const { return curCluster_; } + + /** + * \return The current position for a file or directory. + */ + uint32_t curPosition() const { return curPosition_; } + + /** + * \return Current working directory + */ + static SdBaseFile* cwd() { return cwd_; } + + /** + * Set the date/time callback function * * \param[in] dateTime The user's call back function. The callback * function is of the form: @@ -252,35 +240,55 @@ class SdBaseFile { void (*dateTime)(uint16_t* date, uint16_t* time)) { dateTime_ = dateTime; } - /** Cancel the date/time callback function. */ - static void dateTimeCallbackCancel() {dateTime_ = 0;} + + /** + * Cancel the date/time callback function. + */ + static void dateTimeCallbackCancel() { dateTime_ = 0; } bool dirEntry(dir_t* dir); static void dirName(const dir_t& dir, char* name); bool exists(const char* name); int16_t fgets(char* str, int16_t num, char* delim = 0); - /** \return The total number of bytes in a file or directory. */ - uint32_t fileSize() const {return fileSize_;} - /** \return The first cluster number for a file or directory. */ - uint32_t firstCluster() const {return firstCluster_;} - bool getFilename(char* name); - /** \return True if this is a directory else false. */ - bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} - /** \return True if this is a normal file else false. */ - bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;} - /** \return True if this is an open file/directory else false. */ - bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;} - /** \return True if this is a subdirectory else false. */ - bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;} - /** \return True if this is the root directory. */ - bool isRoot() const { - return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; - } + + /** + * \return The total number of bytes in a file or directory. + */ + uint32_t fileSize() const { return fileSize_; } + + /** + * \return The first cluster number for a file or directory. + */ + uint32_t firstCluster() const { return firstCluster_; } + + /** + * \return True if this is a directory else false. + */ + bool isDir() const { return type_ >= FAT_FILE_TYPE_MIN_DIR; } + + /** + * \return True if this is a normal file else false. + */ + bool isFile() const { return type_ == FAT_FILE_TYPE_NORMAL; } + + /** + * \return True if this is an open file/directory else false. + */ + bool isOpen() const { return type_ != FAT_FILE_TYPE_CLOSED; } + + /** + * \return True if this is a subdirectory else false. + */ + bool isSubDir() const { return type_ == FAT_FILE_TYPE_SUBDIR; } + + /** + * \return True if this is the root directory. + */ + bool isRoot() const { return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; } + + bool getFilename(char * const name); void ls(uint8_t flags = 0, uint8_t indent = 0); + bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); - // alias for backward compactability - bool makeDir(SdBaseFile* dir, const char* path) { - return mkdir(dir, path, false); - } bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); bool open(const char* path, uint8_t oflag = O_READ); @@ -295,53 +303,58 @@ class SdBaseFile { int8_t readDir(dir_t* dir, char* longFilename); static bool remove(SdBaseFile* dirFile, const char* path); bool remove(); - /** Set the file's current position to zero. */ - void rewind() {seekSet(0);} + + /** + * Set the file's current position to zero. + */ + void rewind() { seekSet(0); } bool rename(SdBaseFile* dirFile, const char* newPath); bool rmdir(); - // for backward compatibility - bool rmDir() {return rmdir();} bool rmRfStar(); - /** Set the files position to current position + \a pos. See seekSet(). + + /** + * Set the files position to current position + \a pos. See seekSet(). * \param[in] offset The new position in bytes from the current position. * \return true for success or false for failure. */ - bool seekCur(int32_t offset) { - return seekSet(curPosition_ + offset); - } - /** Set the files position to end-of-file + \a offset. See seekSet(). + bool seekCur(const int32_t offset) { return seekSet(curPosition_ + offset); } + + /** + * Set the files position to end-of-file + \a offset. See seekSet(). * \param[in] offset The new position in bytes from end-of-file. * \return true for success or false for failure. */ - bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);} - bool seekSet(uint32_t pos); + bool seekEnd(const int32_t offset = 0) { return seekSet(fileSize_ + offset); } + bool seekSet(const uint32_t pos); bool sync(); bool timestamp(SdBaseFile* file); bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second); - /** Type of file. You should use isFile() or isDir() instead of type() - * if possible. + + /** + * Type of file. Use isFile() or isDir() instead of type() if possible. * * \return The file or directory type. */ - uint8_t type() const {return type_;} + uint8_t type() const { return type_; } bool truncate(uint32_t size); - /** \return SdVolume that contains this file. */ - SdVolume* volume() const {return vol_;} + + /** + * \return SdVolume that contains this file. + */ + SdVolume* volume() const { return vol_; } int16_t write(const void* buf, uint16_t nbyte); - //------------------------------------------------------------------------------ + private: - // allow SdFat to set cwd_ - friend class SdFat; - // global pointer to cwd dir - static SdBaseFile* cwd_; + friend class SdFat; // allow SdFat to set cwd_ + static SdBaseFile* cwd_; // global pointer to cwd dir + // data time callback function static void (*dateTime_)(uint16_t* date, uint16_t* time); + // bits defined in flags_ - // should be 0x0F - static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); - // sync of directory entry required - static uint8_t const F_FILE_DIR_DIRTY = 0x80; + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC), // should be 0x0F + F_FILE_DIR_DIRTY = 0x80; // sync of directory entry required // private data uint8_t flags_; // See above for definition of flags_ bits @@ -355,8 +368,11 @@ class SdBaseFile { uint32_t firstCluster_; // first cluster of file SdVolume* vol_; // volume where file is located - /** experimental don't use */ - bool openParent(SdBaseFile* dir); + /** + * EXPERIMENTAL - Don't use! + */ + //bool openParent(SdBaseFile* dir); + // private functions bool addCluster(); bool addDirCluster(); @@ -367,61 +383,48 @@ class SdBaseFile { bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag); bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); dir_t* readDirCache(); - //------------------------------------------------------------------------------ - // to be deleted - static void printDirName(const dir_t& dir, - uint8_t width, bool printSlash); - //------------------------------------------------------------------------------ - // Deprecated functions - suppress cpplint warnings with NOLINT comment -#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + +// Deprecated functions +#if ALLOW_DEPRECATED_FUNCTIONS public: - /** \deprecated Use: + + /** + * \deprecated Use: * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); * \param[out] bgnBlock the first block address for the file. * \param[out] endBlock the last block address for the file. * \return true for success or false for failure. */ - bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { return contiguousRange(&bgnBlock, &endBlock); } - /** \deprecated Use: - * bool createContiguous(SdBaseFile* dirFile, - * const char* path, uint32_t size) - * \param[in] dirFile The directory where the file will be created. - * \param[in] path A path with a valid DOS 8.3 file name. - * \param[in] size The desired file size. - * \return true for success or false for failure. - */ - bool createContiguous(SdBaseFile& dirFile, // NOLINT - const char* path, uint32_t size) { + + /** + * \deprecated Use: + * bool createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * \return true for success or false for failure. + */ + bool createContiguous(SdBaseFile& dirFile, const char* path, uint32_t size) { return createContiguous(&dirFile, path, size); } - /** \deprecated Use: + + /** + * \deprecated Use: * static void dateTimeCallback( * void (*dateTime)(uint16_t* date, uint16_t* time)); * \param[in] dateTime The user's call back function. */ static void dateTimeCallback( - void (*dateTime)(uint16_t &date, uint16_t &time)) { // NOLINT + void (*dateTime)(uint16_t &date, uint16_t &time)) { oldDateTime_ = dateTime; dateTime_ = dateTime ? oldToNew : 0; } - /** \deprecated Use: bool dirEntry(dir_t* dir); - * \param[out] dir Location for return of the file's directory entry. - * \return true for success or false for failure. - */ - bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT - /** \deprecated Use: - * bool mkdir(SdBaseFile* dir, const char* path); - * \param[in] dir An open SdFat instance for the directory that will contain - * the new directory. - * \param[in] path A path with a valid 8.3 DOS name for the new directory. - * \return true for success or false for failure. - */ - bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT - return mkdir(&dir, path); - } - /** \deprecated Use: + + /** + * \deprecated Use: * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); * \param[in] dirFile An open SdFat instance for the directory containing the * file to be opened. @@ -430,20 +433,23 @@ class SdBaseFile { * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. * \return true for success or false for failure. */ - bool open(SdBaseFile& dirFile, // NOLINT - const char* path, uint8_t oflag) { + bool open(SdBaseFile& dirFile, const char* path, uint8_t oflag) { return open(&dirFile, path, oflag); } - /** \deprecated Do not use in new apps + + /** + * \deprecated Do not use in new apps * \param[in] dirFile An open SdFat instance for the directory containing the * file to be opened. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. * \return true for success or false for failure. */ - bool open(SdBaseFile& dirFile, const char* path) { // NOLINT + bool open(SdBaseFile& dirFile, const char* path) { return open(dirFile, path, O_RDWR); } - /** \deprecated Use: + + /** + * \deprecated Use: * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); * \param[in] dirFile An open SdFat instance for the directory. * \param[in] index The \a index of the directory entry for the file to be @@ -452,35 +458,39 @@ class SdBaseFile { * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. * \return true for success or false for failure. */ - bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { return open(&dirFile, index, oflag); } - /** \deprecated Use: bool openRoot(SdVolume* vol); + + /** + * \deprecated Use: bool openRoot(SdVolume* vol); * \param[in] vol The FAT volume containing the root directory to be opened. * \return true for success or false for failure. */ - bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT - /** \deprecated Use: int8_t readDir(dir_t* dir); + bool openRoot(SdVolume& vol) { return openRoot(&vol); } + + /** + * \deprecated Use: int8_t readDir(dir_t* dir); * \param[out] dir The dir_t struct that will receive the data. * \return bytes read for success zero for eof or -1 for failure. */ - int8_t readDir(dir_t& dir, char* longFilename) {return readDir(&dir, longFilename);} // NOLINT - /** \deprecated Use: + int8_t readDir(dir_t& dir, char* longFilename) { + return readDir(&dir, longFilename); + } + + /** + * \deprecated Use: * static uint8_t remove(SdBaseFile* dirFile, const char* path); * \param[in] dirFile The directory that contains the file. * \param[in] path The name of the file to be removed. * \return true for success or false for failure. */ - static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT - return remove(&dirFile, path); - } - //------------------------------------------------------------------------------ - // rest are private + static bool remove(SdBaseFile& dirFile, const char* path) { return remove(&dirFile, path); } + private: - static void (*oldDateTime_)(uint16_t &date, uint16_t &time); // NOLINT - static void oldToNew(uint16_t* date, uint16_t* time) { - uint16_t d; - uint16_t t; + static void (*oldDateTime_)(uint16_t &date, uint16_t &time); + static void oldToNew(uint16_t * const date, uint16_t * const time) { + uint16_t d, t; oldDateTime_(d, t); *date = d; *time = t; @@ -488,5 +498,4 @@ class SdBaseFile { #endif // ALLOW_DEPRECATED_FUNCTIONS }; -#endif // SdBaseFile_h -#endif +#endif // _SDBASEFILE_H_ diff --git a/Marlin/SdFatConfig.h b/Marlin/SdFatConfig.h index d3406a0282..606a66f171 100644 --- a/Marlin/SdFatConfig.h +++ b/Marlin/SdFatConfig.h @@ -21,114 +21,101 @@ */ /** + * SdFatConfig.h * Arduino SdFat Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ + +#ifndef _SDFATCONFIG_H_ +#define _SDFATCONFIG_H_ + +#include "MarlinConfig.h" + /** - * \file - * \brief configuration definitions + * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. + * + * Using multiple cards costs 400 - 500 bytes of flash. + * + * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. */ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) +#define USE_MULTIPLE_CARDS 0 -#ifndef SdFatConfig_h - #define SdFatConfig_h - #include - //------------------------------------------------------------------------------ - /** - * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. - * - * Using multiple cards costs 400 - 500 bytes of flash. - * - * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. - */ - #define USE_MULTIPLE_CARDS 0 - //------------------------------------------------------------------------------ - /** - * Call flush for endl if ENDL_CALLS_FLUSH is nonzero - * - * The standard for iostreams is to call flush. This is very costly for - * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. - * - * SdFat has a single 512 byte buffer for SD I/O so it must write the current - * data block to the SD, read the directory block from the SD, update the - * directory entry, write the directory block to the SD and read the data - * block back into the buffer. - * - * The SD flash memory controller is not designed for this many rewrites - * so performance may be reduced by more than a factor of 100. - * - * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force - * all data to be written to the SD. - */ - #define ENDL_CALLS_FLUSH 0 - //------------------------------------------------------------------------------ - /** - * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero - */ - #define ALLOW_DEPRECATED_FUNCTIONS 1 - //------------------------------------------------------------------------------ - /** - * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. - * FAT12 has not been well tested. - */ - #define FAT12_SUPPORT 0 - //------------------------------------------------------------------------------ - /** - * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) - * or 6 (F_CPU/128). - */ - #define SPI_SD_INIT_RATE 5 - //------------------------------------------------------------------------------ - /** - * Set the SS pin high for hardware SPI. If SS is chip select for another SPI - * device this will disable that device during the SD init phase. - */ - #define SET_SPI_SS_HIGH 1 - //------------------------------------------------------------------------------ - /** - * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. - * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. - * - * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used - * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 - * but many SD cards will fail with GPS Shield V1.0. - */ - #define MEGA_SOFT_SPI 0 - //------------------------------------------------------------------------------ - /** - * Set USE_SOFTWARE_SPI nonzero to always use software SPI. - */ - #define USE_SOFTWARE_SPI 0 - // define software SPI pins so Mega can use unmodified 168/328 shields - /** Software SPI chip select pin for the SD */ - #define SOFT_SPI_CS_PIN 10 - /** Software SPI Master Out Slave In pin */ - #define SOFT_SPI_MOSI_PIN 11 - /** Software SPI Master In Slave Out pin */ - #define SOFT_SPI_MISO_PIN 12 - /** Software SPI Clock pin */ - #define SOFT_SPI_SCK_PIN 13 - //------------------------------------------------------------------------------ - /** - * The __cxa_pure_virtual function is an error handler that is invoked when - * a pure virtual function is called. - */ - #define USE_CXA_PURE_VIRTUAL 1 +/** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ +#define ENDL_CALLS_FLUSH 0 - /** Number of UTF-16 characters per entry */ - #define FILENAME_LENGTH 13 +/** + * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero + */ +#define ALLOW_DEPRECATED_FUNCTIONS 1 - /** - * Defines for long (vfat) filenames - */ - /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ - #define MAX_VFAT_ENTRIES (2) - /** Total size of the buffer used to store the long filenames */ - #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) -#endif // SdFatConfig_h +/** + * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. + * FAT12 has not been well tested. + */ +#define FAT12_SUPPORT 0 +/** + * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) + * or 6 (F_CPU/128). + */ +#define SPI_SD_INIT_RATE 5 -#endif +/** + * Set the SS pin high for hardware SPI. If SS is chip select for another SPI + * device this will disable that device during the SD init phase. + */ +#define SET_SPI_SS_HIGH 1 + +/** + * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. + * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * + * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ +#define MEGA_SOFT_SPI 0 + +// Set USE_SOFTWARE_SPI nonzero to ALWAYS use Software SPI. +#define USE_SOFTWARE_SPI 0 + +// Define software SPI pins so Mega can use unmodified 168/328 shields +#define SOFT_SPI_CS_PIN 10 // Software SPI chip select pin for the SD +#define SOFT_SPI_MOSI_PIN 11 // Software SPI Master Out Slave In pin +#define SOFT_SPI_MISO_PIN 12 // Software SPI Master In Slave Out pin +#define SOFT_SPI_SCK_PIN 13 // Software SPI Clock pin + +/** + * The __cxa_pure_virtual function is an error handler that is invoked when + * a pure virtual function is called. + */ +#define USE_CXA_PURE_VIRTUAL 1 + +/** + * Defines for 8.3 and long (vfat) filenames + */ + +#define FILENAME_LENGTH 13 // Number of UTF-16 characters per entry + +// Total bytes needed to store a single long filename +#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * MAX_VFAT_ENTRIES + 1) + +#endif // _SDFATCONFIG_H_ diff --git a/Marlin/SdFatStructs.h b/Marlin/SdFatStructs.h index 52c815d763..7257f3617a 100644 --- a/Marlin/SdFatStructs.h +++ b/Marlin/SdFatStructs.h @@ -20,35 +20,31 @@ * */ +/** + * \file + * \brief FAT file structures + */ + /** * Arduino SdFat Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) - -#ifndef SdFatStructs_h -#define SdFatStructs_h +#ifndef SDFATSTRUCTS_H +#define SDFATSTRUCTS_H #define PACKED __attribute__((__packed__)) -/** - * \file - * \brief FAT file structures - */ + /** * mostly from Microsoft document fatgen103.doc * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx */ -//------------------------------------------------------------------------------ -/** Value for byte 510 of boot block or MBR */ -uint8_t const BOOTSIG0 = 0x55; -/** Value for byte 511 of boot block or MBR */ -uint8_t const BOOTSIG1 = 0xAA; -/** Value for bootSignature field int FAT/FAT32 boot sector */ -uint8_t const EXTENDED_BOOT_SIG = 0x29; -//------------------------------------------------------------------------------ + +uint8_t const BOOTSIG0 = 0x55, // Value for byte 510 of boot block or MBR + BOOTSIG1 = 0xAA, // Value for byte 511 of boot block or MBR + EXTENDED_BOOT_SIG = 0x29; // Value for bootSignature field int FAT/FAT32 boot sector + /** * \struct partitionTable * \brief MBR partition table entry @@ -57,59 +53,58 @@ uint8_t const EXTENDED_BOOT_SIG = 0x29; * The MBR partition table has four entries. */ struct partitionTable { - /** - * Boot Indicator . Indicates whether the volume is the active - * partition. Legal values include: 0x00. Do not use for booting. - * 0x80 Active partition. - */ + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0x00. Do not use for booting. + * 0x80 Active partition. + */ uint8_t boot; - /** - * Head part of Cylinder-head-sector address of the first block in - * the partition. Legal values are 0-255. Only used in old PC BIOS. - */ + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ uint8_t beginHead; - /** - * Sector part of Cylinder-head-sector address of the first block in - * the partition. Legal values are 1-63. Only used in old PC BIOS. - */ + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ unsigned beginSector : 6; - /** High bits cylinder for first block in partition. */ + /** High bits cylinder for first block in partition. */ unsigned beginCylinderHigh : 2; - /** - * Combine beginCylinderLow with beginCylinderHigh. Legal values - * are 0-1023. Only used in old PC BIOS. - */ + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ uint8_t beginCylinderLow; - /** - * Partition type. See defines that begin with PART_TYPE_ for - * some Microsoft partition types. - */ + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ uint8_t type; - /** - * head part of cylinder-head-sector address of the last sector in the - * partition. Legal values are 0-255. Only used in old PC BIOS. - */ + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ uint8_t endHead; - /** - * Sector part of cylinder-head-sector address of the last sector in - * the partition. Legal values are 1-63. Only used in old PC BIOS. - */ + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ unsigned endSector : 6; - /** High bits of end cylinder */ + /** High bits of end cylinder */ unsigned endCylinderHigh : 2; - /** - * Combine endCylinderLow with endCylinderHigh. Legal values - * are 0-1023. Only used in old PC BIOS. - */ + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ uint8_t endCylinderLow; - /** Logical block address of the first block in the partition. */ - uint32_t firstSector; - /** Length of the partition, in blocks. */ - uint32_t totalSectors; + + uint32_t firstSector; // Logical block address of the first block in the partition. + uint32_t totalSectors; // Length of the partition, in blocks. } PACKED; -/** Type name for partitionTable */ -typedef struct partitionTable part_t; -//------------------------------------------------------------------------------ + +typedef struct partitionTable part_t; // Type name for partitionTable + /** * \struct masterBootRecord * @@ -118,22 +113,16 @@ typedef struct partitionTable part_t; * The first block of a storage device that is formatted with a MBR. */ struct masterBootRecord { - /** Code Area for master boot program. */ - uint8_t codeArea[440]; - /** Optional Windows NT disk signature. May contain boot code. */ - uint32_t diskSignature; - /** Usually zero but may be more boot code. */ - uint16_t usuallyZero; - /** Partition tables. */ - part_t part[4]; - /** First MBR signature byte. Must be 0x55 */ - uint8_t mbrSig0; - /** Second MBR signature byte. Must be 0xAA */ - uint8_t mbrSig1; + uint8_t codeArea[440]; // Code Area for master boot program. + uint32_t diskSignature; // Optional Windows NT disk signature. May contain boot code. + uint16_t usuallyZero; // Usually zero but may be more boot code. + part_t part[4]; // Partition tables. + uint8_t mbrSig0; // First MBR signature byte. Must be 0x55 + uint8_t mbrSig1; // Second MBR signature byte. Must be 0xAA } PACKED; /** Type name for masterBootRecord */ typedef struct masterBootRecord mbr_t; -//------------------------------------------------------------------------------ + /** * \struct fat_boot * @@ -141,285 +130,280 @@ typedef struct masterBootRecord mbr_t; * */ struct fat_boot { - /** - * The first three bytes of the boot sector must be valid, - * executable x 86-based CPU instructions. This includes a - * jump instruction that skips the next nonexecutable bytes. - */ + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ uint8_t jump[3]; - /** - * This is typically a string of characters that identifies - * the operating system that formatted the volume. - */ + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ char oemId[8]; - /** - * The size of a hardware sector. Valid decimal values for this - * field are 512, 1024, 2048, and 4096. For most disks used in - * the United States, the value of this field is 512. - */ + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ uint16_t bytesPerSector; - /** - * Number of sectors per allocation unit. This value must be a - * power of 2 that is greater than 0. The legal values are - * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. - */ + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ uint8_t sectorsPerCluster; - /** - * The number of sectors preceding the start of the first FAT, - * including the boot sector. The value of this field is always 1. - */ + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ uint16_t reservedSectorCount; - /** - * The number of copies of the FAT on the volume. - * The value of this field is always 2. - */ + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ uint8_t fatCount; - /** - * For FAT12 and FAT16 volumes, this field contains the count of - * 32-byte directory entries in the root directory. For FAT32 volumes, - * this field must be set to 0. For FAT12 and FAT16 volumes, this - * value should always specify a count that when multiplied by 32 - * results in a multiple of bytesPerSector. FAT16 volumes should - * use the value 512. - */ + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ uint16_t rootDirEntryCount; - /** - * This field is the old 16-bit total count of sectors on the volume. - * This count includes the count of all sectors in all four regions - * of the volume. This field can be 0; if it is 0, then totalSectors32 - * must be nonzero. For FAT32 volumes, this field must be 0. For - * FAT12 and FAT16 volumes, this field contains the sector count, and - * totalSectors32 is 0 if the total sector count fits - * (is less than 0x10000). - */ + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ uint16_t totalSectors16; - /** - * This dates back to the old MS-DOS 1.x media determination and is - * no longer usually used for anything. 0xF8 is the standard value - * for fixed (nonremovable) media. For removable media, 0xF0 is - * frequently used. Legal values are 0xF0 or 0xF8-0xFF. - */ + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ uint8_t mediaType; - /** - * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. - * On FAT32 volumes this field must be 0, and sectorsPerFat32 - * contains the FAT size count. - */ + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ uint16_t sectorsPerFat16; - /** Sectors per track for interrupt 0x13. Not used otherwise. */ - uint16_t sectorsPerTrack; - /** Number of heads for interrupt 0x13. Not used otherwise. */ - uint16_t headCount; - /** - * Count of hidden sectors preceding the partition that contains this - * FAT volume. This field is generally only relevant for media - * visible on interrupt 0x13. - */ + + uint16_t sectorsPerTrack; // Sectors per track for interrupt 0x13. Not used otherwise. + uint16_t headCount; // Number of heads for interrupt 0x13. Not used otherwise. + + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ uint32_t hidddenSectors; - /** - * This field is the new 32-bit total count of sectors on the volume. - * This count includes the count of all sectors in all four regions - * of the volume. This field can be 0; if it is 0, then - * totalSectors16 must be nonzero. - */ + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ uint32_t totalSectors32; - /** - * Related to the BIOS physical drive number. Floppy drives are - * identified as 0x00 and physical hard disks are identified as - * 0x80, regardless of the number of physical disk drives. - * Typically, this value is set prior to issuing an INT 13h BIOS - * call to specify the device to access. The value is only - * relevant if the device is a boot device. - */ + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ uint8_t driveNumber; - /** used by Windows NT - should be zero for FAT */ - uint8_t reserved1; - /** 0x29 if next three fields are valid */ - uint8_t bootSignature; - /** - * A random serial number created when formatting a disk, - * which helps to distinguish between disks. - * Usually generated by combining date and time. - */ + + uint8_t reserved1; // used by Windows NT - should be zero for FAT + uint8_t bootSignature; // 0x29 if next three fields are valid + + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ uint32_t volumeSerialNumber; - /** - * A field once used to store the volume label. The volume label - * is now stored as a special file in the root directory. - */ + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ char volumeLabel[11]; - /** - * A field with a value of either FAT, FAT12 or FAT16, - * depending on the disk format. - */ + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ char fileSystemType[8]; - /** X86 boot code */ - uint8_t bootCode[448]; - /** must be 0x55 */ - uint8_t bootSectorSig0; - /** must be 0xAA */ - uint8_t bootSectorSig1; + + uint8_t bootCode[448]; // X86 boot code + uint8_t bootSectorSig0; // must be 0x55 + uint8_t bootSectorSig1; // must be 0xAA } PACKED; -/** Type name for FAT Boot Sector */ -typedef struct fat_boot fat_boot_t; -//------------------------------------------------------------------------------ + +typedef struct fat_boot fat_boot_t; // Type name for FAT Boot Sector + /** * \struct fat32_boot * * \brief Boot sector for a FAT32 volume. - * */ struct fat32_boot { - /** - * The first three bytes of the boot sector must be valid, - * executable x 86-based CPU instructions. This includes a - * jump instruction that skips the next nonexecutable bytes. - */ + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ uint8_t jump[3]; - /** - * This is typically a string of characters that identifies - * the operating system that formatted the volume. - */ + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ char oemId[8]; - /** - * The size of a hardware sector. Valid decimal values for this - * field are 512, 1024, 2048, and 4096. For most disks used in - * the United States, the value of this field is 512. - */ + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ uint16_t bytesPerSector; - /** - * Number of sectors per allocation unit. This value must be a - * power of 2 that is greater than 0. The legal values are - * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. - */ + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ uint8_t sectorsPerCluster; - /** - * The number of sectors preceding the start of the first FAT, - * including the boot sector. Must not be zero - */ + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ uint16_t reservedSectorCount; - /** - * The number of copies of the FAT on the volume. - * The value of this field is always 2. - */ + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ uint8_t fatCount; - /** - * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. - */ + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ uint16_t rootDirEntryCount; - /** - * For FAT32 volumes, this field must be 0. - */ + /** + * For FAT32 volumes, this field must be 0. + */ uint16_t totalSectors16; - /** - * This dates back to the old MS-DOS 1.x media determination and is - * no longer usually used for anything. 0xF8 is the standard value - * for fixed (nonremovable) media. For removable media, 0xF0 is - * frequently used. Legal values are 0xF0 or 0xF8-0xFF. - */ + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ uint8_t mediaType; - /** - * On FAT32 volumes this field must be 0, and sectorsPerFat32 - * contains the FAT size count. - */ + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ uint16_t sectorsPerFat16; - /** Sectors per track for interrupt 0x13. Not used otherwise. */ - uint16_t sectorsPerTrack; - /** Number of heads for interrupt 0x13. Not used otherwise. */ - uint16_t headCount; - /** - * Count of hidden sectors preceding the partition that contains this - * FAT volume. This field is generally only relevant for media - * visible on interrupt 0x13. - */ + + uint16_t sectorsPerTrack; // Sectors per track for interrupt 0x13. Not used otherwise. + uint16_t headCount; // Number of heads for interrupt 0x13. Not used otherwise. + + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ uint32_t hidddenSectors; - /** - * Contains the total number of sectors in the FAT32 volume. - */ + /** + * Contains the total number of sectors in the FAT32 volume. + */ uint32_t totalSectors32; - /** - * Count of sectors occupied by one FAT on FAT32 volumes. - */ + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ uint32_t sectorsPerFat32; - /** - * This field is only defined for FAT32 media and does not exist on - * FAT12 and FAT16 media. - * Bits 0-3 -- Zero-based number of active FAT. - * Only valid if mirroring is disabled. - * Bits 4-6 -- Reserved. - * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. - * -- 1 means only one FAT is active; it is the one referenced - * in bits 0-3. - * Bits 8-15 -- Reserved. - */ + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ uint16_t fat32Flags; - /** - * FAT32 version. High byte is major revision number. - * Low byte is minor revision number. Only 0.0 define. - */ + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ uint16_t fat32Version; - /** - * Cluster number of the first cluster of the root directory for FAT32. - * This usually 2 but not required to be 2. - */ + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ uint32_t fat32RootCluster; - /** - * Sector number of FSINFO structure in the reserved area of the - * FAT32 volume. Usually 1. - */ + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ uint16_t fat32FSInfo; - /** - * If nonzero, indicates the sector number in the reserved area - * of the volume of a copy of the boot record. Usually 6. - * No value other than 6 is recommended. - */ + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ uint16_t fat32BackBootBlock; - /** - * Reserved for future expansion. Code that formats FAT32 volumes - * should always set all of the bytes of this field to 0. - */ + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ uint8_t fat32Reserved[12]; - /** - * Related to the BIOS physical drive number. Floppy drives are - * identified as 0x00 and physical hard disks are identified as - * 0x80, regardless of the number of physical disk drives. - * Typically, this value is set prior to issuing an INT 13h BIOS - * call to specify the device to access. The value is only - * relevant if the device is a boot device. - */ + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ uint8_t driveNumber; - /** used by Windows NT - should be zero for FAT */ - uint8_t reserved1; - /** 0x29 if next three fields are valid */ - uint8_t bootSignature; - /** - * A random serial number created when formatting a disk, - * which helps to distinguish between disks. - * Usually generated by combining date and time. - */ + + uint8_t reserved1; // Used by Windows NT - should be zero for FAT + uint8_t bootSignature; // 0x29 if next three fields are valid + + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ uint32_t volumeSerialNumber; - /** - * A field once used to store the volume label. The volume label - * is now stored as a special file in the root directory. - */ + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ char volumeLabel[11]; - /** - * A text field with a value of FAT32. - */ + /** + * A text field with a value of FAT32. + */ char fileSystemType[8]; - /** X86 boot code */ - uint8_t bootCode[420]; - /** must be 0x55 */ - uint8_t bootSectorSig0; - /** must be 0xAA */ - uint8_t bootSectorSig1; + + uint8_t bootCode[420]; // X86 boot code + uint8_t bootSectorSig0; // must be 0x55 + uint8_t bootSectorSig1; // must be 0xAA + } PACKED; -/** Type name for FAT32 Boot Sector */ -typedef struct fat32_boot fat32_boot_t; -//------------------------------------------------------------------------------ -/** Lead signature for a FSINFO sector */ -uint32_t const FSINFO_LEAD_SIG = 0x41615252; -/** Struct signature for a FSINFO sector */ -uint32_t const FSINFO_STRUCT_SIG = 0x61417272; + +typedef struct fat32_boot fat32_boot_t; // Type name for FAT32 Boot Sector + +uint32_t const FSINFO_LEAD_SIG = 0x41615252, // 'AaRR' Lead signature for a FSINFO sector + FSINFO_STRUCT_SIG = 0x61417272; // 'aArr' Struct signature for a FSINFO sector + /** * \struct fat32_fsinfo * @@ -427,12 +411,9 @@ uint32_t const FSINFO_STRUCT_SIG = 0x61417272; * */ struct fat32_fsinfo { - /** must be 0x52, 0x52, 0x61, 0x41 */ - uint32_t leadSignature; - /** must be zero */ - uint8_t reserved1[480]; - /** must be 0x72, 0x72, 0x41, 0x61 */ - uint32_t structSignature; + uint32_t leadSignature; // must be 0x52, 0x52, 0x61, 0x41 'RRaA' + uint8_t reserved1[480]; // must be zero + uint32_t structSignature; // must be 0x72, 0x72, 0x41, 0x61 'rrAa' /** * Contains the last known free cluster count on the volume. * If the value is 0xFFFFFFFF, then the free count is unknown @@ -448,30 +429,22 @@ struct fat32_fsinfo { * should start looking at cluster 2. */ uint32_t nextFree; - /** must be zero */ - uint8_t reserved2[12]; - /** must be 0x00, 0x00, 0x55, 0xAA */ - uint8_t tailSignature[4]; + + uint8_t reserved2[12]; // must be zero + uint8_t tailSignature[4]; // must be 0x00, 0x00, 0x55, 0xAA } PACKED; -/** Type name for FAT32 FSINFO Sector */ -typedef struct fat32_fsinfo fat32_fsinfo_t; -//------------------------------------------------------------------------------ + +typedef struct fat32_fsinfo fat32_fsinfo_t; // Type name for FAT32 FSINFO Sector + // End Of Chain values for FAT entries -/** FAT12 end of chain value used by Microsoft. */ -uint16_t const FAT12EOC = 0xFFF; -/** Minimum value for FAT12 EOC. Use to test for EOC. */ -uint16_t const FAT12EOC_MIN = 0xFF8; -/** FAT16 end of chain value used by Microsoft. */ -uint16_t const FAT16EOC = 0xFFFF; -/** Minimum value for FAT16 EOC. Use to test for EOC. */ -uint16_t const FAT16EOC_MIN = 0xFFF8; -/** FAT32 end of chain value used by Microsoft. */ -uint32_t const FAT32EOC = 0x0FFFFFFF; -/** Minimum value for FAT32 EOC. Use to test for EOC. */ -uint32_t const FAT32EOC_MIN = 0x0FFFFFF8; -/** Mask a for FAT32 entry. Entries are 28 bits. */ -uint32_t const FAT32MASK = 0x0FFFFFFF; -//------------------------------------------------------------------------------ +uint16_t const FAT12EOC = 0xFFF, // FAT12 end of chain value used by Microsoft. + FAT12EOC_MIN = 0xFF8, // Minimum value for FAT12 EOC. Use to test for EOC. + FAT16EOC = 0xFFFF, // FAT16 end of chain value used by Microsoft. + FAT16EOC_MIN = 0xFFF8; // Minimum value for FAT16 EOC. Use to test for EOC. +uint32_t const FAT32EOC = 0x0FFFFFFF, // FAT32 end of chain value used by Microsoft. + FAT32EOC_MIN = 0x0FFFFFF8, // Minimum value for FAT32 EOC. Use to test for EOC. + FAT32MASK = 0x0FFFFFFF; // Mask a for FAT32 entry. Entries are 28 bits. + /** * \struct directoryEntry * \brief FAT short directory entry @@ -503,54 +476,54 @@ uint32_t const FAT32MASK = 0x0FFFFFFF; * The valid time range is from Midnight 00:00:00 to 23:59:58. */ struct directoryEntry { - /** Short 8.3 name. - * - * The first eight bytes contain the file name with blank fill. - * The last three bytes contain the file extension with blank fill. - */ + /** + * Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ uint8_t name[11]; - /** Entry attributes. - * - * The upper two bits of the attribute byte are reserved and should - * always be set to 0 when a file is created and never modified or - * looked at after that. See defines that begin with DIR_ATT_. - */ + /** + * Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ uint8_t attributes; - /** - * Reserved for use by Windows NT. Set value to 0 when a file is - * created and never modify or look at it after that. - */ + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ uint8_t reservedNT; - /** - * The granularity of the seconds part of creationTime is 2 seconds - * so this field is a count of tenths of a second and it's valid - * value range is 0-199 inclusive. (WHG note - seems to be hundredths) - */ + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and it's valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ uint8_t creationTimeTenths; - /** Time file was created. */ - uint16_t creationTime; - /** Date file was created. */ - uint16_t creationDate; - /** - * Last access date. Note that there is no last access time, only - * a date. This is the date of last read or write. In the case of - * a write, this should be set to the same date as lastWriteDate. - */ + + uint16_t creationTime; // Time file was created. + uint16_t creationDate; // Date file was created. + + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ uint16_t lastAccessDate; - /** - * High word of this entry's first cluster number (always 0 for a - * FAT12 or FAT16 volume). - */ + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ uint16_t firstClusterHigh; - /** Time of last write. File creation is considered a write. */ - uint16_t lastWriteTime; - /** Date of last write. File creation is considered a write. */ - uint16_t lastWriteDate; - /** Low word of this entry's first cluster number. */ - uint16_t firstClusterLow; - /** 32-bit unsigned holding this file's size in bytes. */ - uint32_t fileSize; + + uint16_t lastWriteTime; // Time of last write. File creation is considered a write. + uint16_t lastWriteDate; // Date of last write. File creation is considered a write. + uint16_t firstClusterLow; // Low word of this entry's first cluster number. + uint32_t fileSize; // 32-bit unsigned holding this file's size in bytes. } PACKED; + /** * \struct directoryVFATEntry * \brief VFAT long filename directory entry @@ -568,54 +541,36 @@ struct directoryVFATEntry { * bit 0-4: the position of this long filename block (first block is 1) */ uint8_t sequenceNumber; - /** First set of UTF-16 characters */ - uint16_t name1[5];//UTF-16 - /** attributes (at the same location as in directoryEntry), always 0x0F */ - uint8_t attributes; - /** Reserved for use by Windows NT. Always 0. */ - uint8_t reservedNT; - /** Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. */ - uint8_t checksum; - /** Second set of UTF-16 characters */ - uint16_t name2[6];//UTF-16 - /** firstClusterLow is always zero for longFilenames */ - uint16_t firstClusterLow; - /** Third set of UTF-16 characters */ - uint16_t name3[2];//UTF-16 + + uint16_t name1[5]; // First set of UTF-16 characters + uint8_t attributes; // attributes (at the same location as in directoryEntry), always 0x0F + uint8_t reservedNT; // Reserved for use by Windows NT. Always 0. + uint8_t checksum; // Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. + uint16_t name2[6]; // Second set of UTF-16 characters + uint16_t firstClusterLow; // firstClusterLow is always zero for longFilenames + uint16_t name3[2]; // Third set of UTF-16 characters } PACKED; -//------------------------------------------------------------------------------ + // Definitions for directory entries // -/** Type name for directoryEntry */ -typedef struct directoryEntry dir_t; -/** Type name for directoryVFATEntry */ -typedef struct directoryVFATEntry vfat_t; -/** escape for name[0] = 0xE5 */ -uint8_t const DIR_NAME_0xE5 = 0x05; -/** name[0] value for entry that is free after being "deleted" */ -uint8_t const DIR_NAME_DELETED = 0xE5; -/** name[0] value for entry that is free and no allocated entries follow */ -uint8_t const DIR_NAME_FREE = 0x00; -/** file is read-only */ -uint8_t const DIR_ATT_READ_ONLY = 0x01; -/** File should hidden in directory listings */ -uint8_t const DIR_ATT_HIDDEN = 0x02; -/** Entry is for a system file */ -uint8_t const DIR_ATT_SYSTEM = 0x04; -/** Directory entry contains the volume label */ -uint8_t const DIR_ATT_VOLUME_ID = 0x08; -/** Entry is for a directory */ -uint8_t const DIR_ATT_DIRECTORY = 0x10; -/** Old DOS archive bit for backup support */ -uint8_t const DIR_ATT_ARCHIVE = 0x20; -/** Test value for long name entry. Test is - (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ -uint8_t const DIR_ATT_LONG_NAME = 0x0F; -/** Test mask for long name entry */ -uint8_t const DIR_ATT_LONG_NAME_MASK = 0x3F; -/** defined attribute bits */ -uint8_t const DIR_ATT_DEFINED_BITS = 0x3F; -/** Directory entry is part of a long name +typedef struct directoryEntry dir_t; // Type name for directoryEntry +typedef struct directoryVFATEntry vfat_t; // Type name for directoryVFATEntry + +uint8_t const DIR_NAME_0xE5 = 0x05, // escape for name[0] = 0xE5 + DIR_NAME_DELETED = 0xE5, // name[0] value for entry that is free after being "deleted" + DIR_NAME_FREE = 0x00, // name[0] value for entry that is free and no allocated entries follow + DIR_ATT_READ_ONLY = 0x01, // file is read-only + DIR_ATT_HIDDEN = 0x02, // File should hidden in directory listings + DIR_ATT_SYSTEM = 0x04, // Entry is for a system file + DIR_ATT_VOLUME_ID = 0x08, // Directory entry contains the volume label + DIR_ATT_DIRECTORY = 0x10, // Entry is for a directory + DIR_ATT_ARCHIVE = 0x20, // Old DOS archive bit for backup support + DIR_ATT_LONG_NAME = 0x0F, // Test value for long name entry. Test is (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. + DIR_ATT_LONG_NAME_MASK = 0x3F, // Test mask for long name entry + DIR_ATT_DEFINED_BITS = 0x3F; // defined attribute bits + +/** + * Directory entry is part of a long name * \param[in] dir Pointer to a directory entry. * * \return true if the entry is for part of a long name else false. @@ -623,9 +578,12 @@ uint8_t const DIR_ATT_DEFINED_BITS = 0x3F; static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; } + /** Mask for file/subdirectory tests */ uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); -/** Directory entry is for a file + +/** + * Directory entry is for a file * \param[in] dir Pointer to a directory entry. * * \return true if the entry is for a normal file else false. @@ -633,7 +591,9 @@ uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); static inline uint8_t DIR_IS_FILE(const dir_t* dir) { return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; } -/** Directory entry is for a subdirectory + +/** + * Directory entry is for a subdirectory * \param[in] dir Pointer to a directory entry. * * \return true if the entry is for a subdirectory else false. @@ -641,7 +601,9 @@ static inline uint8_t DIR_IS_FILE(const dir_t* dir) { static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; } -/** Directory entry is for a file or subdirectory + +/** + * Directory entry is for a file or subdirectory * \param[in] dir Pointer to a directory entry. * * \return true if the entry is for a normal file or subdirectory else false. @@ -649,7 +611,5 @@ static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; } -#endif // SdFatStructs_h - -#endif +#endif // SDFATSTRUCTS_H diff --git a/Marlin/SdFatUtil.cpp b/Marlin/SdFatUtil.cpp index 48d91df682..1d8cdb434f 100644 --- a/Marlin/SdFatUtil.cpp +++ b/Marlin/SdFatUtil.cpp @@ -26,13 +26,15 @@ * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(SDSUPPORT) -#include "SdFatUtil.h" -//------------------------------------------------------------------------------ -/** Amount of free RAM +#include "SdFatUtil.h" +#include "serial.h" + +/** + * Amount of free RAM * \return The number of free bytes. */ #ifdef __arm__ @@ -44,7 +46,8 @@ int SdFatUtil::FreeRam() { #else // __arm__ extern char* __brkval; extern char __bss_end; -/** Amount of free RAM +/** + * Amount of free RAM * \return The number of free bytes. */ int SdFatUtil::FreeRam() { @@ -53,8 +56,8 @@ int SdFatUtil::FreeRam() { } #endif // __arm -//------------------------------------------------------------------------------ -/** %Print a string in flash memory. +/** + * %Print a string in flash memory. * * \param[in] pr Print object for output. * \param[in] str Pointer to string stored in flash memory. @@ -62,30 +65,27 @@ int SdFatUtil::FreeRam() { void SdFatUtil::print_P(PGM_P str) { for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c); } -//------------------------------------------------------------------------------ -/** %Print a string in flash memory followed by a CR/LF. + +/** + * %Print a string in flash memory followed by a CR/LF. * * \param[in] pr Print object for output. * \param[in] str Pointer to string stored in flash memory. */ -void SdFatUtil::println_P(PGM_P str) { - print_P(str); - MYSERIAL.println(); -} -//------------------------------------------------------------------------------ -/** %Print a string in flash memory to Serial. +void SdFatUtil::println_P(PGM_P str) { print_P(str); MYSERIAL.println(); } + +/** + * %Print a string in flash memory to Serial. * * \param[in] str Pointer to string stored in flash memory. */ -void SdFatUtil::SerialPrint_P(PGM_P str) { - print_P(str); -} -//------------------------------------------------------------------------------ -/** %Print a string in flash memory to Serial followed by a CR/LF. +void SdFatUtil::SerialPrint_P(PGM_P str) { print_P(str); } + +/** + * %Print a string in flash memory to Serial followed by a CR/LF. * * \param[in] str Pointer to string stored in flash memory. */ -void SdFatUtil::SerialPrintln_P(PGM_P str) { - println_P(str); -} -#endif +void SdFatUtil::SerialPrintln_P(PGM_P str) { println_P(str); } + +#endif // SDSUPPORT diff --git a/Marlin/SdFatUtil.h b/Marlin/SdFatUtil.h index 2e6435bbdc..793ba2f078 100644 --- a/Marlin/SdFatUtil.h +++ b/Marlin/SdFatUtil.h @@ -26,11 +26,8 @@ * * This file is part of the Arduino Sd2Card Library */ -#ifndef SdFatUtil_h -#define SdFatUtil_h - -#include "Marlin.h" -#if ENABLED(SDSUPPORT) +#ifndef _SDFATUTIL_H_ +#define _SDFATUTIL_H_ /** * \file @@ -51,6 +48,4 @@ namespace SdFatUtil { using namespace SdFatUtil; // NOLINT -#endif // SDSUPPORT - -#endif // SdFatUtil_h +#endif // _SDFATUTIL_H_ diff --git a/Marlin/SdFile.cpp b/Marlin/SdFile.cpp index fc66f4173b..45d18e01b3 100644 --- a/Marlin/SdFile.cpp +++ b/Marlin/SdFile.cpp @@ -26,21 +26,24 @@ * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(SDSUPPORT) + #include "SdFile.h" -/** Create a file object and open it in the current working directory. + +/** + * Create a file object and open it in the current working directory. * * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. * * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). */ -SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { -} -//------------------------------------------------------------------------------ -/** Write data to an open file. +SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { } + +/** + * Write data to an open file. * * \note Data is moved to the cache but may not be written to the * storage device until sync() is called. @@ -55,41 +58,37 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { * for a read-only file, device is full, a corrupt file system or an I/O error. * */ -int16_t SdFile::write(const void* buf, uint16_t nbyte) { - return SdBaseFile::write(buf, nbyte); -} -//------------------------------------------------------------------------------ -/** Write a byte to a file. Required by the Arduino Print class. +int16_t SdFile::write(const void* buf, uint16_t nbyte) { return SdBaseFile::write(buf, nbyte); } + +/** + * Write a byte to a file. Required by the Arduino Print class. * \param[in] b the byte to be written. * Use writeError to check for errors. */ #if ARDUINO >= 100 - size_t SdFile::write(uint8_t b) { - return SdBaseFile::write(&b, 1); - } + size_t SdFile::write(uint8_t b) { return SdBaseFile::write(&b, 1); } #else - void SdFile::write(uint8_t b) { - SdBaseFile::write(&b, 1); - } + void SdFile::write(uint8_t b) { SdBaseFile::write(&b, 1); } #endif -//------------------------------------------------------------------------------ -/** Write a string to a file. Used by the Arduino Print class. + +/** + * Write a string to a file. Used by the Arduino Print class. * \param[in] str Pointer to the string. * Use writeError to check for errors. */ -void SdFile::write(const char* str) { - SdBaseFile::write(str, strlen(str)); -} -//------------------------------------------------------------------------------ -/** Write a PROGMEM string to a file. +void SdFile::write(const char* str) { SdBaseFile::write(str, strlen(str)); } + +/** + * Write a PROGMEM string to a file. * \param[in] str Pointer to the PROGMEM string. * Use writeError to check for errors. */ void SdFile::write_P(PGM_P str) { for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); } -//------------------------------------------------------------------------------ -/** Write a PROGMEM string followed by CR/LF to a file. + +/** + * Write a PROGMEM string followed by CR/LF to a file. * \param[in] str Pointer to the PROGMEM string. * Use writeError to check for errors. */ @@ -98,5 +97,4 @@ void SdFile::writeln_P(PGM_P str) { write_P(PSTR("\r\n")); } - -#endif +#endif // SDSUPPORT diff --git a/Marlin/SdFile.h b/Marlin/SdFile.h index 53f38255cb..36d6862d8d 100644 --- a/Marlin/SdFile.h +++ b/Marlin/SdFile.h @@ -20,24 +20,23 @@ * */ +/** + * \file + * \brief SdFile class + */ + /** * Arduino SdFat Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ -/** - * \file - * \brief SdFile class - */ -#include "Marlin.h" +#ifndef _SDFILE_H_ +#define _SDFILE_H_ -#if ENABLED(SDSUPPORT) #include "SdBaseFile.h" #include -#ifndef SdFile_h -#define SdFile_h -//------------------------------------------------------------------------------ + /** * \class SdFile * \brief SdBaseFile with Print. @@ -57,7 +56,5 @@ class SdFile : public SdBaseFile, public Print { void write_P(PGM_P str); void writeln_P(PGM_P str); }; -#endif // SdFile_h - -#endif +#endif // _SDFILE_H_ diff --git a/Marlin/SdInfo.h b/Marlin/SdInfo.h index 88b4656908..9fe121f168 100644 --- a/Marlin/SdInfo.h +++ b/Marlin/SdInfo.h @@ -26,12 +26,11 @@ * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) +#ifndef _SDINFO_H_ +#define _SDINFO_H_ -#ifndef SdInfo_h -#define SdInfo_h #include + // Based on the document: // // SD Specifications @@ -42,46 +41,26 @@ // May 18, 2010 // // http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs -//------------------------------------------------------------------------------ + // SD card commands -/** GO_IDLE_STATE - init card in spi mode if CS low */ -uint8_t const CMD0 = 0x00; -/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ -uint8_t const CMD8 = 0x08; -/** SEND_CSD - read the Card Specific Data (CSD register) */ -uint8_t const CMD9 = 0x09; -/** SEND_CID - read the card identification information (CID register) */ -uint8_t const CMD10 = 0x0A; -/** STOP_TRANSMISSION - end multiple block read sequence */ -uint8_t const CMD12 = 0x0C; -/** SEND_STATUS - read the card status register */ -uint8_t const CMD13 = 0x0D; -/** READ_SINGLE_BLOCK - read a single data block from the card */ -uint8_t const CMD17 = 0x11; -/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ -uint8_t const CMD18 = 0x12; -/** WRITE_BLOCK - write a single data block to the card */ -uint8_t const CMD24 = 0x18; -/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ -uint8_t const CMD25 = 0x19; -/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ -uint8_t const CMD32 = 0x20; -/** ERASE_WR_BLK_END - sets the address of the last block of the continuous - range to be erased*/ -uint8_t const CMD33 = 0x21; -/** ERASE - erase all previously selected blocks */ -uint8_t const CMD38 = 0x26; -/** APP_CMD - escape for application specific command */ -uint8_t const CMD55 = 0x37; -/** READ_OCR - read the OCR register of a card */ -uint8_t const CMD58 = 0x3A; -/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be - pre-erased before writing */ -uint8_t const ACMD23 = 0x17; -/** SD_SEND_OP_COMD - Sends host capacity support information and - activates the card's initialization process */ -uint8_t const ACMD41 = 0x29; -//------------------------------------------------------------------------------ +uint8_t const CMD0 = 0x00, // GO_IDLE_STATE - init card in spi mode if CS low + CMD8 = 0x08, // SEND_IF_COND - verify SD Memory Card interface operating condition + CMD9 = 0x09, // SEND_CSD - read the Card Specific Data (CSD register) + CMD10 = 0x0A, // SEND_CID - read the card identification information (CID register) + CMD12 = 0x0C, // STOP_TRANSMISSION - end multiple block read sequence + CMD13 = 0x0D, // SEND_STATUS - read the card status register + CMD17 = 0x11, // READ_SINGLE_BLOCK - read a single data block from the card + CMD18 = 0x12, // READ_MULTIPLE_BLOCK - read a multiple data blocks from the card + CMD24 = 0x18, // WRITE_BLOCK - write a single data block to the card + CMD25 = 0x19, // WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION + CMD32 = 0x20, // ERASE_WR_BLK_START - sets the address of the first block to be erased + CMD33 = 0x21, // ERASE_WR_BLK_END - sets the address of the last block of the continuous range to be erased*/ + CMD38 = 0x26, // ERASE - erase all previously selected blocks */ + CMD55 = 0x37, // APP_CMD - escape for application specific command */ + CMD58 = 0x3A, // READ_OCR - read the OCR register of a card */ + ACMD23 = 0x17, // SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be pre-erased before writing */ + ACMD41 = 0x29; // SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */ + /** status for card in the ready state */ uint8_t const R1_READY_STATE = 0x00; /** status for card in the idle state */ @@ -98,7 +77,7 @@ uint8_t const WRITE_MULTIPLE_TOKEN = 0xFC; uint8_t const DATA_RES_MASK = 0x1F; /** write data accepted token */ uint8_t const DATA_RES_ACCEPTED = 0x05; -//------------------------------------------------------------------------------ + /** Card IDentification (CID) register */ typedef struct CID { // byte 0 @@ -134,7 +113,7 @@ typedef struct CID { /** CRC7 checksum */ unsigned char crc : 7; } cid_t; -//------------------------------------------------------------------------------ + /** CSD for version 1.00 cards */ typedef struct CSDV1 { // byte 0 @@ -196,7 +175,7 @@ typedef struct CSDV1 { unsigned char always1 : 1; unsigned char crc : 7; } csd1_t; -//------------------------------------------------------------------------------ + /** CSD for version 2.00 cards */ typedef struct CSDV2 { // byte 0 @@ -278,12 +257,11 @@ typedef struct CSDV2 { /** checksum */ unsigned char crc : 7; } csd2_t; -//------------------------------------------------------------------------------ + /** union of old and new style CSD register */ union csd_t { csd1_t v1; csd2_t v2; }; -#endif // SdInfo_h -#endif +#endif // _SDINFO_H_ diff --git a/Marlin/SdVolume.cpp b/Marlin/SdVolume.cpp index 4093cb5e04..bf8abc5797 100644 --- a/Marlin/SdVolume.cpp +++ b/Marlin/SdVolume.cpp @@ -26,11 +26,12 @@ * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" +#include "MarlinConfig.h" + #if ENABLED(SDSUPPORT) #include "SdVolume.h" -//------------------------------------------------------------------------------ + #if !USE_MULTIPLE_CARDS // raw block cache uint32_t SdVolume::cacheBlockNumber_; // current block number @@ -39,7 +40,7 @@ bool SdVolume::cacheDirty_; // cacheFlush() will write block if true uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT #endif // USE_MULTIPLE_CARDS -//------------------------------------------------------------------------------ + // find a contiguous group of clusters bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { // start of group @@ -73,14 +74,14 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { // search the FAT for free clusters for (uint32_t n = 0;; n++, endCluster++) { // can't find space checked all clusters - if (n >= clusterCount_) goto FAIL; + if (n >= clusterCount_) return false; // past end - start from beginning of FAT if (endCluster > fatEnd) { bgnCluster = endCluster = 2; } uint32_t f; - if (!fatGet(endCluster, &f)) goto FAIL; + if (!fatGet(endCluster, &f)) return false; if (f != 0) { // cluster in use try next cluster as bgnCluster @@ -92,16 +93,16 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { } } // mark end of chain - if (!fatPutEOC(endCluster)) goto FAIL; + if (!fatPutEOC(endCluster)) return false; // link clusters while (endCluster > bgnCluster) { - if (!fatPut(endCluster - 1, endCluster)) goto FAIL; + if (!fatPut(endCluster - 1, endCluster)) return false; endCluster--; } if (*curCluster != 0) { // connect chains - if (!fatPut(*curCluster, bgnCluster)) goto FAIL; + if (!fatPut(*curCluster, bgnCluster)) return false; } // return first cluster number to caller *curCluster = bgnCluster; @@ -110,111 +111,94 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { if (setStart) allocSearchStart_ = bgnCluster + 1; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + bool SdVolume::cacheFlush() { if (cacheDirty_) { - if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { - goto FAIL; - } + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) + return false; + // mirror FAT tables if (cacheMirrorBlock_) { - if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { - goto FAIL; - } + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) + return false; cacheMirrorBlock_ = 0; } cacheDirty_ = 0; } return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) { if (cacheBlockNumber_ != blockNumber) { - if (!cacheFlush()) goto FAIL; - if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto FAIL; + if (!cacheFlush()) return false; + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false; cacheBlockNumber_ = blockNumber; } if (dirty) cacheDirty_ = true; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + // return the size in bytes of a cluster chain bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) { uint32_t s = 0; do { - if (!fatGet(cluster, &cluster)) goto FAIL; + if (!fatGet(cluster, &cluster)) return false; s += 512UL << clusterSizeShift_; } while (!isEOC(cluster)); *size = s; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + // Fetch a FAT entry bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { uint32_t lba; - if (cluster > (clusterCount_ + 1)) goto FAIL; + if (cluster > (clusterCount_ + 1)) return false; if (FAT12_SUPPORT && fatType_ == 12) { uint16_t index = cluster; index += index >> 1; lba = fatStartBlock_ + (index >> 9); - if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL; + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; index &= 0x1FF; uint16_t tmp = cacheBuffer_.data[index]; index++; if (index == 512) { - if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto FAIL; + if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) return false; index = 0; } tmp |= cacheBuffer_.data[index] << 8; *value = cluster & 1 ? tmp >> 4 : tmp & 0xFFF; return true; } - if (fatType_ == 16) { + + if (fatType_ == 16) lba = fatStartBlock_ + (cluster >> 8); - } - else if (fatType_ == 32) { + else if (fatType_ == 32) lba = fatStartBlock_ + (cluster >> 7); - } - else { - goto FAIL; - } - if (lba != cacheBlockNumber_) { - if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL; - } - if (fatType_ == 16) { - *value = cacheBuffer_.fat16[cluster & 0xFF]; - } - else { - *value = cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK; - } + else + return false; + + if (lba != cacheBlockNumber_ && !cacheRawBlock(lba, CACHE_FOR_READ)) + return false; + + *value = (fatType_ == 16) ? cacheBuffer_.fat16[cluster & 0xFF] : (cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK); return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + // Store a FAT entry bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { uint32_t lba; // error if reserved cluster - if (cluster < 2) goto FAIL; + if (cluster < 2) return false; // error if not in FAT - if (cluster > (clusterCount_ + 1)) goto FAIL; + if (cluster > (clusterCount_ + 1)) return false; if (FAT12_SUPPORT && fatType_ == 12) { uint16_t index = cluster; index += index >> 1; lba = fatStartBlock_ + (index >> 9); - if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false; // mirror second FAT if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; index &= 0x1FF; @@ -227,7 +211,7 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { if (index == 512) { lba++; index = 0; - if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false; // mirror second FAT if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; } @@ -238,51 +222,45 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { cacheBuffer_.data[index] = tmp; return true; } - if (fatType_ == 16) { + + if (fatType_ == 16) lba = fatStartBlock_ + (cluster >> 8); - } - else if (fatType_ == 32) { + else if (fatType_ == 32) lba = fatStartBlock_ + (cluster >> 7); - } - else { - goto FAIL; - } - if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + else + return false; + + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false; + // store entry - if (fatType_ == 16) { + if (fatType_ == 16) cacheBuffer_.fat16[cluster & 0xFF] = value; - } - else { + else cacheBuffer_.fat32[cluster & 0x7F] = value; - } + // mirror second FAT if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + // free a cluster chain bool SdVolume::freeChain(uint32_t cluster) { - uint32_t next; - // clear free cluster location allocSearchStart_ = 2; do { - if (!fatGet(cluster, &next)) goto FAIL; + uint32_t next; + if (!fatGet(cluster, &next)) return false; // free cluster - if (!fatPut(cluster, 0)) goto FAIL; + if (!fatPut(cluster, 0)) return false; cluster = next; } while (!isEOC(cluster)); return true; - FAIL: - return false; } -//------------------------------------------------------------------------------ + /** Volume free space in clusters. * * \return Count of free clusters for success or -1 if an error occurs. @@ -292,34 +270,28 @@ int32_t SdVolume::freeClusterCount() { uint16_t n; uint32_t todo = clusterCount_ + 2; - if (fatType_ == 16) { + if (fatType_ == 16) n = 256; - } - else if (fatType_ == 32) { + else if (fatType_ == 32) n = 128; - } - else { - // put FAT12 here + else // put FAT12 here return -1; - } for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) { if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1; NOMORE(n, todo); if (fatType_ == 16) { - for (uint16_t i = 0; i < n; i++) { + for (uint16_t i = 0; i < n; i++) if (cacheBuffer_.fat16[i] == 0) free++; - } } else { - for (uint16_t i = 0; i < n; i++) { + for (uint16_t i = 0; i < n; i++) if (cacheBuffer_.fat32[i] == 0) free++; - } } } return free; } -//------------------------------------------------------------------------------ + /** Initialize a FAT volume. * * \param[in] dev The SD card where the volume is located. @@ -329,14 +301,12 @@ int32_t SdVolume::freeClusterCount() { * a MBR, Master Boot Record, or zero if the device is formatted as * a super floppy with the FAT boot sector in block zero. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. Reasons for - * failure include not finding a valid partition, not finding a valid + * \return true for success, false for failure. + * Reasons for failure include not finding a valid partition, not finding a valid * FAT file system in the specified partition or an I/O error. */ bool SdVolume::init(Sd2Card* dev, uint8_t part) { - uint32_t totalBlocks; - uint32_t volumeStartBlock = 0; + uint32_t totalBlocks, volumeStartBlock = 0; fat32_boot_t* fbs; sdCard_ = dev; @@ -349,25 +319,21 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) { // if part == 0 assume super floppy with FAT boot sector in block zero // if part > 0 assume mbr volume with partition table if (part) { - if (part > 4)goto FAIL; - if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL; + if (part > 4) return false; + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; part_t* p = &cacheBuffer_.mbr.part[part - 1]; - if ((p->boot & 0x7F) != 0 || - p->totalSectors < 100 || - p->firstSector == 0) { - // not a valid partition - goto FAIL; - } + if ((p->boot & 0x7F) != 0 || p->totalSectors < 100 || p->firstSector == 0) + return false; // not a valid partition volumeStartBlock = p->firstSector; } - if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL; + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; fbs = &cacheBuffer_.fbs32; if (fbs->bytesPerSector != 512 || fbs->fatCount == 0 || fbs->reservedSectorCount == 0 || fbs->sectorsPerCluster == 0) { // not valid FAT volume - goto FAIL; + return false; } fatCount_ = fbs->fatCount; blocksPerCluster_ = fbs->sectorsPerCluster; @@ -375,7 +341,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) { clusterSizeShift_ = 0; while (blocksPerCluster_ != _BV(clusterSizeShift_)) { // error if not power of 2 - if (clusterSizeShift_++ > 7) goto FAIL; + if (clusterSizeShift_++ > 7) return false; } blocksPerFat_ = fbs->sectorsPerFat16 ? fbs->sectorsPerFat16 : fbs->sectorsPerFat32; @@ -404,17 +370,15 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) { // FAT type is determined by cluster count if (clusterCount_ < 4085) { fatType_ = 12; - if (!FAT12_SUPPORT) goto FAIL; + if (!FAT12_SUPPORT) return false; } - else if (clusterCount_ < 65525) { + else if (clusterCount_ < 65525) fatType_ = 16; - } else { rootDirStart_ = fbs->fat32RootCluster; fatType_ = 32; } return true; - FAIL: - return false; } -#endif + +#endif // SDSUPPORT diff --git a/Marlin/SdVolume.h b/Marlin/SdVolume.h index 3041a6dfb4..7cde194ebe 100644 --- a/Marlin/SdVolume.h +++ b/Marlin/SdVolume.h @@ -20,20 +20,20 @@ * */ +/** + * \file + * \brief SdVolume class + */ + /** * Arduino SdFat Library * Copyright (C) 2009 by William Greiman * * This file is part of the Arduino Sd2Card Library */ -#include "Marlin.h" -#if ENABLED(SDSUPPORT) -#ifndef SdVolume_h -#define SdVolume_h -/** - * \file - * \brief SdVolume class - */ +#ifndef _SDVOLUME_H_ +#define _SDVOLUME_H_ + #include "SdFatConfig.h" #include "Sd2Card.h" #include "SdFatStructs.h" @@ -44,33 +44,26 @@ * \brief Cache for an SD data block */ union cache_t { - /** Used to access cached file data blocks. */ - uint8_t data[512]; - /** Used to access cached FAT16 entries. */ - uint16_t fat16[256]; - /** Used to access cached FAT32 entries. */ - uint32_t fat32[128]; - /** Used to access cached directory entries. */ - dir_t dir[16]; - /** Used to access a cached Master Boot Record. */ - mbr_t mbr; - /** Used to access to a cached FAT boot sector. */ - fat_boot_t fbs; - /** Used to access to a cached FAT32 boot sector. */ - fat32_boot_t fbs32; - /** Used to access to a cached FAT32 FSINFO sector. */ - fat32_fsinfo_t fsinfo; + uint8_t data[512]; // Used to access cached file data blocks. + uint16_t fat16[256]; // Used to access cached FAT16 entries. + uint32_t fat32[128]; // Used to access cached FAT32 entries. + dir_t dir[16]; // Used to access cached directory entries. + mbr_t mbr; // Used to access a cached Master Boot Record. + fat_boot_t fbs; // Used to access to a cached FAT boot sector. + fat32_boot_t fbs32; // Used to access to a cached FAT32 boot sector. + fat32_fsinfo_t fsinfo; // Used to access to a cached FAT32 FSINFO sector. }; -//------------------------------------------------------------------------------ + /** * \class SdVolume * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. */ class SdVolume { public: - /** Create an instance of SdVolume */ + // Create an instance of SdVolume SdVolume() : fatType_(0) {} - /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + /** + * Clear the cache and returns a pointer to the cache. Used by the WaveRP * recorder to do raw write to the SD card. Not for normal apps. * \return A pointer to the cache buffer or zero if an error occurs. */ @@ -79,54 +72,53 @@ class SdVolume { cacheBlockNumber_ = 0xFFFFFFFF; return &cacheBuffer_; } - /** Initialize a FAT volume. Try partition one first then try super + + /** + * Initialize a FAT volume. Try partition one first then try super * floppy format. * * \param[in] dev The Sd2Card where the volume is located. * - * \return The value one, true, is returned for success and - * the value zero, false, is returned for failure. Reasons for - * failure include not finding a valid partition, not finding a valid - * FAT file system or an I/O error. + * \return true for success, false for failure. + * Reasons for failure include not finding a valid partition, not finding + * a valid FAT file system or an I/O error. */ - bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0); } bool init(Sd2Card* dev, uint8_t part); // inline functions that return volume info - /** \return The volume's cluster size in blocks. */ - uint8_t blocksPerCluster() const {return blocksPerCluster_;} - /** \return The number of blocks in one FAT. */ - uint32_t blocksPerFat() const {return blocksPerFat_;} - /** \return The total number of clusters in the volume. */ - uint32_t clusterCount() const {return clusterCount_;} - /** \return The shift count required to multiply by blocksPerCluster. */ - uint8_t clusterSizeShift() const {return clusterSizeShift_;} - /** \return The logical block number for the start of file data. */ - uint32_t dataStartBlock() const {return dataStartBlock_;} - /** \return The number of FAT structures on the volume. */ - uint8_t fatCount() const {return fatCount_;} - /** \return The logical block number for the start of the first FAT. */ - uint32_t fatStartBlock() const {return fatStartBlock_;} - /** \return The FAT type of the volume. Values are 12, 16 or 32. */ - uint8_t fatType() const {return fatType_;} + uint8_t blocksPerCluster() const { return blocksPerCluster_; } //> \return The volume's cluster size in blocks. + uint32_t blocksPerFat() const { return blocksPerFat_; } //> \return The number of blocks in one FAT. + uint32_t clusterCount() const { return clusterCount_; } //> \return The total number of clusters in the volume. + uint8_t clusterSizeShift() const { return clusterSizeShift_; } //> \return The shift count required to multiply by blocksPerCluster. + uint32_t dataStartBlock() const { return dataStartBlock_; } //> \return The logical block number for the start of file data. + uint8_t fatCount() const { return fatCount_; } //> \return The number of FAT structures on the volume. + uint32_t fatStartBlock() const { return fatStartBlock_; } //> \return The logical block number for the start of the first FAT. + uint8_t fatType() const { return fatType_; } //> \return The FAT type of the volume. Values are 12, 16 or 32. int32_t freeClusterCount(); - /** \return The number of entries in the root directory for FAT16 volumes. */ - uint32_t rootDirEntryCount() const {return rootDirEntryCount_;} - /** \return The logical block number for the start of the root directory - on FAT16 volumes or the first cluster number on FAT32 volumes. */ - uint32_t rootDirStart() const {return rootDirStart_;} - /** Sd2Card object for this volume + uint32_t rootDirEntryCount() const { return rootDirEntryCount_; } /** \return The number of entries in the root directory for FAT16 volumes. */ + + /** + * \return The logical block number for the start of the root directory + * on FAT16 volumes or the first cluster number on FAT32 volumes. + */ + uint32_t rootDirStart() const { return rootDirStart_; } + + /** + * Sd2Card object for this volume * \return pointer to Sd2Card object. */ - Sd2Card* sdCard() {return sdCard_;} - /** Debug access to FAT table + Sd2Card* sdCard() { return sdCard_; } + + /** + * Debug access to FAT table * * \param[in] n cluster number. * \param[out] v value of entry * \return true for success or false for failure */ - bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} - //------------------------------------------------------------------------------ + bool dbgFat(uint32_t n, uint32_t* v) { return fatGet(n, v); } + private: // Allow SdBaseFile access to SdVolume private data. friend class SdBaseFile; @@ -136,19 +128,20 @@ class SdVolume { // value for dirty argument in cacheRawBlock to indicate write to cache static bool const CACHE_FOR_WRITE = true; -#if USE_MULTIPLE_CARDS - cache_t cacheBuffer_; // 512 byte cache for device blocks - uint32_t cacheBlockNumber_; // Logical number of block in the cache - Sd2Card* sdCard_; // Sd2Card object for cache - bool cacheDirty_; // cacheFlush() will write block if true - uint32_t cacheMirrorBlock_; // block number for mirror FAT -#else // USE_MULTIPLE_CARDS - static cache_t cacheBuffer_; // 512 byte cache for device blocks - static uint32_t cacheBlockNumber_; // Logical number of block in the cache - static Sd2Card* sdCard_; // Sd2Card object for cache - static bool cacheDirty_; // cacheFlush() will write block if true - static uint32_t cacheMirrorBlock_; // block number for mirror FAT -#endif // USE_MULTIPLE_CARDS + #if USE_MULTIPLE_CARDS + cache_t cacheBuffer_; // 512 byte cache for device blocks + uint32_t cacheBlockNumber_; // Logical number of block in the cache + Sd2Card* sdCard_; // Sd2Card object for cache + bool cacheDirty_; // cacheFlush() will write block if true + uint32_t cacheMirrorBlock_; // block number for mirror FAT + #else + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static bool cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT + #endif + uint32_t allocSearchStart_; // start cluster for alloc search uint8_t blocksPerCluster_; // cluster size in blocks uint32_t blocksPerFat_; // FAT size in blocks @@ -160,68 +153,59 @@ class SdVolume { uint8_t fatType_; // volume type (12, 16, OR 32) uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 - //---------------------------------------------------------------------------- + bool allocContiguous(uint32_t count, uint32_t* curCluster); - uint8_t blockOfCluster(uint32_t position) const { - return (position >> 9) & (blocksPerCluster_ - 1); - } - uint32_t clusterStartBlock(uint32_t cluster) const { - return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); - } - uint32_t blockNumber(uint32_t cluster, uint32_t position) const { - return clusterStartBlock(cluster) + blockOfCluster(position); - } - cache_t* cache() {return &cacheBuffer_;} - uint32_t cacheBlockNumber() {return cacheBlockNumber_;} -#if USE_MULTIPLE_CARDS - bool cacheFlush(); - bool cacheRawBlock(uint32_t blockNumber, bool dirty); -#else // USE_MULTIPLE_CARDS - static bool cacheFlush(); - static bool cacheRawBlock(uint32_t blockNumber, bool dirty); -#endif // USE_MULTIPLE_CARDS + uint8_t blockOfCluster(uint32_t position) const { return (position >> 9) & (blocksPerCluster_ - 1); } + uint32_t clusterStartBlock(uint32_t cluster) const { return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); } + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { return clusterStartBlock(cluster) + blockOfCluster(position); } + + cache_t* cache() { return &cacheBuffer_; } + uint32_t cacheBlockNumber() const { return cacheBlockNumber_; } + + #if USE_MULTIPLE_CARDS + bool cacheFlush(); + bool cacheRawBlock(uint32_t blockNumber, bool dirty); + #else + static bool cacheFlush(); + static bool cacheRawBlock(uint32_t blockNumber, bool dirty); + #endif + // used by SdBaseFile write to assign cache to SD location void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) { cacheDirty_ = dirty; cacheBlockNumber_ = blockNumber; } - void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;} + void cacheSetDirty() { cacheDirty_ |= CACHE_FOR_WRITE; } bool chainSize(uint32_t beginCluster, uint32_t* size); bool fatGet(uint32_t cluster, uint32_t* value); bool fatPut(uint32_t cluster, uint32_t value); - bool fatPutEOC(uint32_t cluster) { - return fatPut(cluster, 0x0FFFFFFF); - } + bool fatPutEOC(uint32_t cluster) { return fatPut(cluster, 0x0FFFFFFF); } bool freeChain(uint32_t cluster); bool isEOC(uint32_t cluster) const { if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN; if (fatType_ == 16) return cluster >= FAT16EOC_MIN; return cluster >= FAT32EOC_MIN; } - bool readBlock(uint32_t block, uint8_t* dst) { - return sdCard_->readBlock(block, dst); - } - bool writeBlock(uint32_t block, const uint8_t* dst) { - return sdCard_->writeBlock(block, dst); - } - //------------------------------------------------------------------------------ - // Deprecated functions - suppress cpplint warnings with NOLINT comment -#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) - public: - /** \deprecated Use: bool SdVolume::init(Sd2Card* dev); - * \param[in] dev The SD card where the volume is located. - * \return true for success or false for failure. - */ - bool init(Sd2Card& dev) {return init(&dev);} // NOLINT - /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); - * \param[in] dev The SD card where the volume is located. - * \param[in] part The partition to be used. - * \return true for success or false for failure. - */ - bool init(Sd2Card& dev, uint8_t part) { // NOLINT - return init(&dev, part); - } -#endif // ALLOW_DEPRECATED_FUNCTIONS + bool readBlock(uint32_t block, uint8_t* dst) { return sdCard_->readBlock(block, dst); } + bool writeBlock(uint32_t block, const uint8_t* dst) { return sdCard_->writeBlock(block, dst); } + + // Deprecated functions + #if ALLOW_DEPRECATED_FUNCTIONS + public: + /** + * \deprecated Use: bool SdVolume::init(Sd2Card* dev); + * \param[in] dev The SD card where the volume is located. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev) { return init(&dev); } + /** + * \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); + * \param[in] dev The SD card where the volume is located. + * \param[in] part The partition to be used. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev, uint8_t part) { return init(&dev, part); } + #endif // ALLOW_DEPRECATED_FUNCTIONS }; -#endif // SdVolume -#endif + +#endif // _SDVOLUME_H_ diff --git a/Marlin/Version.h b/Marlin/Version.h index 3039da59bc..f55eae1c5b 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -48,7 +48,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ - #define STRING_DISTRIBUTION_DATE "2017-10-10 12:00" + #define STRING_DISTRIBUTION_DATE "2017-10-24 12:00" /** * Required minimum Configuration.h and Configuration_adv.h file versions. @@ -57,8 +57,8 @@ * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option on * the configuration files. */ - #define REQUIRED_CONFIGURATION_H_VERSION 010100 - #define REQUIRED_CONFIGURATION_ADV_H_VERSION 010100 + #define REQUIRED_CONFIGURATION_H_VERSION 010107 + #define REQUIRED_CONFIGURATION_ADV_H_VERSION 010107 /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/bitmap_flags.h b/Marlin/bitmap_flags.h new file mode 100644 index 0000000000..7f7d04f5dd --- /dev/null +++ b/Marlin/bitmap_flags.h @@ -0,0 +1,38 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 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 . + * + */ + +#ifndef _BITMAP_FLAGS_H_ +#define _BITMAP_FLAGS_H_ + +#include "macros.h" + +/** + * These support functions allow the use of large bit arrays of flags that take very + * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration + * to unsigned long will allow us to go to 32x32 if higher resolution meshes are needed + * in the future. + */ +FORCE_INLINE void bitmap_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); } +FORCE_INLINE void bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); } +FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); } + +#endif // _BITMAP_FLAGS_H_ diff --git a/Marlin/blinkm.cpp b/Marlin/blinkm.cpp index 1caf0a071e..7eba6c0d92 100644 --- a/Marlin/blinkm.cpp +++ b/Marlin/blinkm.cpp @@ -21,26 +21,26 @@ */ /** - * blinkm.cpp - Library for controlling a BlinkM over i2c - * Created by Tim Koster, August 21 2013. + * blinkm.cpp - Control a BlinkM over i2c */ -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(BLINKM) #include "blinkm.h" +#include "leds.h" +#include -void SendColors(byte red, byte grn, byte blu) { +void blinkm_set_led_color(const LEDColor &color) { Wire.begin(); Wire.beginTransmission(0x09); Wire.write('o'); //to disable ongoing script, only needs to be used once Wire.write('n'); - Wire.write(red); - Wire.write(grn); - Wire.write(blu); + Wire.write(color.r); + Wire.write(color.g); + Wire.write(color.b); Wire.endTransmission(); } #endif // BLINKM - diff --git a/Marlin/blinkm.h b/Marlin/blinkm.h index ed2ad79bb2..20e84d9a95 100644 --- a/Marlin/blinkm.h +++ b/Marlin/blinkm.h @@ -21,11 +21,15 @@ */ /** - * blinkm.h - Library for controlling a BlinkM over i2c - * Created by Tim Koster, August 21 2013. + * blinkm.h - Control a BlinkM over i2c */ -#include "Arduino.h" -#include "Wire.h" +#ifndef _BLINKM_H_ +#define _BLINKM_H_ -void SendColors(byte red, byte grn, byte blu); +struct LEDColor; +typedef LEDColor LEDColor; + +void blinkm_set_led_color(const LEDColor &color); + +#endif // _BLINKM_H_ diff --git a/Marlin/boards.h b/Marlin/boards.h index 398165e46c..1948695788 100644 --- a/Marlin/boards.h +++ b/Marlin/boards.h @@ -25,81 +25,127 @@ #define BOARD_UNKNOWN -1 -#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" -#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 -#define BOARD_GEN7_13 12 // Gen7 v1.3 -#define BOARD_GEN7_14 13 // Gen7 v1.4 -#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 -#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 -#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 -#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0 -#define BOARD_SETHI 20 // Sethi 3D_1 -#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E -#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 -#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) -#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) -#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard -#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 -#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) -#define BOARD_GEN6 5 // Gen6 -#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe -#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 -#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above -#define BOARD_MELZI 63 // Melzi -#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) -#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc) -#define BOARD_STB_11 64 // STB V1.1 -#define BOARD_AZTEEG_X1 65 // Azteeg X1 -#define BOARD_AZTEEG_X3 67 // Azteeg X3 -#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro -#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone) -#define BOARD_ULTIMAKER 7 // Ultimaker -#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) -#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) -#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A -#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe) -#define BOARD_3DRAG 77 // 3Drag Controller -#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) -#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) -#define BOARD_TEENSYLU 8 // Teensylu -#define BOARD_RUMBA 80 // Rumba -#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) -#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) -#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) -#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) -#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make -#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) -#define BOARD_GEN3_PLUS 9 // Gen3+ -#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics -#define BOARD_MEGATRONICS 70 // Megatronics -#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 -#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 -#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 -#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1 -#define BOARD_OMCA_A 90 // Alpha OMCA board -#define BOARD_OMCA 91 // Final OMCA board -#define BOARD_RAMBO 301 // Rambo -#define BOARD_MINIRAMBO 302 // Mini-Rambo -#define BOARD_SCOOVO_X9H 303 // abee Scoovo X9H -#define BOARD_MEGACONTROLLER 310 // Mega controller -#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3) -#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board -#define BOARD_LEAPFROG 999 // Leapfrog -#define BOARD_MKS_BASE 40 // MKS BASE 1.0 -#define BOARD_MKS_13 47 // MKS v1.3 or 1.4 (maybe higher) -#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board -#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers -#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers -#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D -#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) +// +// RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 +// + +#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 + +#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) + +#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) + +#define BOARD_RAMPS_PLUS_EFB 143 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_PLUS_EEB 144 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_PLUS_EFF 145 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_PLUS_EEF 146 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_PLUS_SF 148 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) + +// +// RAMPS Derivatives - ATmega1280, ATmega2560 +// + +#define BOARD_3DRAG 77 // 3Drag Controller +#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) +#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) +#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers +#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers +#define BOARD_MKS_BASE 40 // MKS BASE 1.0 +#define BOARD_MKS_13 47 // MKS v1.3 or 1.4 (maybe higher) +#define BOARD_MKS_GEN_L 53 // MKS GEN L +#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) +#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) +#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard +#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 +#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board +#define BOARD_ULTIMAKER 7 // Ultimaker +#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) +#define BOARD_AZTEEG_X3 67 // Azteeg X3 +#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro +#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) +#define BOARD_RUMBA 80 // Rumba +#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D +#define BOARD_MAKEBOARD_MINI 431 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake + +// +// Other ATmega1280, ATmega2560 +// + +#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 +#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 +#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 +#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0 +#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E +#define BOARD_MEGATRONICS 70 // Megatronics +#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 +#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 +#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1 +#define BOARD_RAMBO 301 // Rambo +#define BOARD_MINIRAMBO 302 // Mini-Rambo +#define BOARD_MINIRAMBO_10A 303 // Mini-Rambo 1.0a +#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3) +#define BOARD_LEAPFROG 999 // Leapfrog +#define BOARD_MEGACONTROLLER 310 // Mega controller +#define BOARD_SCOOVO_X9H 321 // abee Scoovo X9H +#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A +#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe) + +// +// ATmega1281, ATmega2561 +// + +#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 +#define BOARD_SILVER_GATE 25 // Silvergate v1.0 + +// +// Sanguinololu and Derivatives - ATmega644P, ATmega1284P +// + +#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 +#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above +#define BOARD_MELZI 63 // Melzi +#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) +#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc) +#define BOARD_STB_11 64 // STB V1.1 +#define BOARD_AZTEEG_X1 65 // Azteeg X1 + +// +// Other ATmega644P, ATmega644, ATmega1284P +// + +#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics +#define BOARD_GEN3_PLUS 9 // Gen3+ +#define BOARD_GEN6 5 // Gen6 +#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe +#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" +#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 +#define BOARD_GEN7_13 12 // Gen7 v1.3 +#define BOARD_GEN7_14 13 // Gen7 v1.4 +#define BOARD_OMCA_A 90 // Alpha OMCA board +#define BOARD_OMCA 91 // Final OMCA board +#define BOARD_SETHI 20 // Sethi 3D_1 +#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone) + +// +// Teensyduino - AT90USB1286, AT90USB1286P +// + +#define BOARD_TEENSYLU 8 // Teensylu +#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) +#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) +#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) +#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) +#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) +#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make +#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board #define MB(board) (MOTHERBOARD==BOARD_##board) diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp index 89147d97b6..c1b42e8913 100644 --- a/Marlin/cardreader.cpp +++ b/Marlin/cardreader.cpp @@ -20,16 +20,16 @@ * */ +#include "MarlinConfig.h" + +#if ENABLED(SDSUPPORT) + #include "cardreader.h" #include "ultralcd.h" #include "stepper.h" #include "language.h" -#include "Marlin.h" - -#if ENABLED(SDSUPPORT) - #define LONGEST_FILENAME (longFilename[0] ? longFilename : filename) CardReader::CardReader() { @@ -44,8 +44,9 @@ CardReader::CardReader() { sdprinting = cardOK = saving = logging = false; filesize = 0; sdpos = 0; - workDirDepth = 0; file_subcall_ctr = 0; + + workDirDepth = 0; ZERO(workDirParents); autostart_stilltocheck = true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. @@ -73,9 +74,12 @@ char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters /** * Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: * LS_Count - Add +1 to nrFiles for every file within the parent - * LS_GetFilename - Get the filename of the file indexed by nrFiles + * LS_GetFilename - Get the filename of the file indexed by nrFile_index * LS_SerialPrint - Print the full path and size of each file to serial output */ + +uint16_t nrFile_index; + void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { dir_t p; uint8_t cnt = 0; @@ -129,7 +133,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; - switch (lsAction) { + switch (lsAction) { // 1 based file count case LS_Count: nrFiles++; break; @@ -147,7 +151,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (match != NULL) { if (strcasecmp(match, filename) == 0) return; } - else if (cnt == nrFiles) return; + else if (cnt == nrFile_index) return; // 0 based index cnt++; break; } @@ -255,16 +259,7 @@ void CardReader::initsd() { SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_SD_CARD_OK); } - workDir = root; - curDir = &root; - #if ENABLED(SDCARD_SORT_ALPHA) - presort(); - #endif - /** - if (!workDir.openRoot(&volume)) { - SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); - } - */ + setroot(); } void CardReader::setroot() { @@ -310,26 +305,33 @@ void CardReader::openLogFile(char* name) { openFile(name, false); } -void CardReader::getAbsFilename(char *t) { - uint8_t cnt = 0; - *t = '/'; t++; cnt++; - for (uint8_t i = 0; i < workDirDepth; i++) { - workDirParents[i].getFilename(t); //SDBaseFile.getfilename! - while (*t && cnt < MAXPATHNAMELENGTH) { t++; cnt++; } //crawl counter forward. - } - if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) - file.getFilename(t); - else - t[0] = 0; +void appendAtom(SdFile &file, char *& dst, uint8_t &cnt) { + file.getFilename(dst); + while (*dst && cnt < MAXPATHNAMELENGTH) { dst++; cnt++; } + if (cnt < MAXPATHNAMELENGTH) { *dst = '/'; dst++; cnt++; } } -void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { +void CardReader::getAbsFilename(char *t) { + *t++ = '/'; // Root folder + uint8_t cnt = 1; + + for (uint8_t i = 0; i < workDirDepth; i++) // Loop to current work dir + appendAtom(workDirParents[i], t, cnt); + + if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) { + appendAtom(file, t, cnt); + --t; + } + *t = '\0'; +} + +void CardReader::openFile(char* name, const bool read, const bool subcall/*=false*/) { if (!cardOK) return; uint8_t doing = 0; - if (isFileOpen()) { //replacing current file by new file, or subfile call - if (push_current) { + if (isFileOpen()) { // Replacing current file or doing a subroutine + if (subcall) { if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) { SERIAL_ERROR_START(); SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); @@ -338,21 +340,24 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { return; } - // Store current filename and position + // Store current filename (based on workDirParents) and position getAbsFilename(proc_filenames[file_subcall_ctr]); + filespos[file_subcall_ctr] = sdpos; SERIAL_ECHO_START(); SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name); SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]); SERIAL_ECHOLNPAIR("\" pos", sdpos); - filespos[file_subcall_ctr] = sdpos; file_subcall_ctr++; } - else { + else doing = 1; - } } - else { // Opening fresh file + else if (subcall) { // Returning from a subcall? + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("END SUBROUTINE"); + } + else { // Opening fresh file doing = 2; file_subcall_ctr = 0; // Reset procedure depth in case user cancels print while in procedure } @@ -360,7 +365,7 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { if (doing) { SERIAL_ECHO_START(); SERIAL_ECHOPGM("Now "); - SERIAL_ECHO(doing == 1 ? "doing" : "fresh"); + serialprintPGM(doing == 1 ? PSTR("doing") : PSTR("fresh")); SERIAL_ECHOLNPAIR(" file: ", name); } @@ -380,8 +385,7 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { if (dirname_end != NULL && dirname_end > dirname_start) { char subdirname[FILENAME_LENGTH]; strncpy(subdirname, dirname_start, dirname_end - dirname_start); - subdirname[dirname_end - dirname_start] = 0; - SERIAL_ECHOLN(subdirname); + subdirname[dirname_end - dirname_start] = '\0'; if (!myDir.open(curDir, subdirname, O_READ)) { SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(subdirname); @@ -403,17 +407,15 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { } } } - else { //relative path - curDir = &workDir; - } + else + curDir = &workDir; // Relative paths start in current directory if (read) { if (file.open(curDir, fname, O_READ)) { filesize = file.fileSize(); + sdpos = 0; SERIAL_PROTOCOLPAIR(MSG_SD_FILE_OPENED, fname); SERIAL_PROTOCOLLNPAIR(MSG_SD_SIZE, filesize); - sdpos = 0; - SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED); getfilename(0, fname); lcd_setstatus(longFilename[0] ? longFilename : fname); @@ -438,14 +440,14 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { } } -void CardReader::removeFile(char* name) { +void CardReader::removeFile(const char * const name) { if (!cardOK) return; stopSDPrint(); SdFile myDir; curDir = &root; - char *fname = name; + const char *fname = name; char *dirname_start, *dirname_end; if (name[0] == '/') { @@ -460,29 +462,23 @@ void CardReader::removeFile(char* name) { subdirname[dirname_end - dirname_start] = 0; SERIAL_ECHOLN(subdirname); if (!myDir.open(curDir, subdirname, O_READ)) { - SERIAL_PROTOCOLPAIR("open failed, File: ", subdirname); + SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, subdirname); SERIAL_PROTOCOLCHAR('.'); SERIAL_EOL(); return; } - else { - //SERIAL_ECHOLNPGM("dive ok"); - } curDir = &myDir; dirname_start = dirname_end + 1; } - else { // the remainder after all /fsa/fdsa/ is the filename + else { fname = dirname_start; - //SERIAL_ECHOLNPGM("remainder"); - //SERIAL_ECHOLN(fname); break; } } } - else { // relative path + else // Relative paths are rooted in the current directory curDir = &workDir; - } if (file.remove(curDir, fname)) { SERIAL_PROTOCOLPGM("File deleted:"); @@ -506,14 +502,13 @@ void CardReader::getStatus() { SERIAL_PROTOCOLCHAR('/'); SERIAL_PROTOCOLLN(filesize); } - else { + else SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); - } } void CardReader::write_command(char *buf) { char* begin = buf; - char* npos = 0; + char* npos = NULL; char* end = buf + strlen(buf) - 1; file.writeError = false; @@ -595,7 +590,7 @@ void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) { #endif // SDSORT_CACHE_NAMES curDir = &workDir; lsAction = LS_GetFilename; - nrFiles = nr; + nrFile_index = nr; curDir->rewind(); lsDive("", *curDir, match); } @@ -611,33 +606,34 @@ uint16_t CardReader::getnrfilenames() { } void CardReader::chdir(const char * relpath) { - SdFile newfile; + SdFile newDir; SdFile *parent = &root; if (workDir.isOpen()) parent = &workDir; - if (!newfile.open(*parent, relpath, O_READ)) { + if (!newDir.open(*parent, relpath, O_READ)) { SERIAL_ECHO_START(); SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); SERIAL_ECHOLN(relpath); } else { + workDir = newDir; if (workDirDepth < MAX_DIR_DEPTH) - workDirParents[workDirDepth++] = *parent; - workDir = newfile; + workDirParents[workDirDepth++] = workDir; #if ENABLED(SDCARD_SORT_ALPHA) presort(); #endif } } -void CardReader::updir() { - if (workDirDepth > 0) { - workDir = workDirParents[--workDirDepth]; +int8_t CardReader::updir() { + if (workDirDepth > 0) { // At least 1 dir has been saved + workDir = --workDirDepth ? workDirParents[workDirDepth - 1] : root; // Use parent, or root if none #if ENABLED(SDCARD_SORT_ALPHA) presort(); #endif } + return workDirDepth; } #if ENABLED(SDCARD_SORT_ALPHA) @@ -696,7 +692,7 @@ void CardReader::updir() { sortnames = new char*[fileCnt]; #endif #elif ENABLED(SDSORT_USES_STACK) - char sortnames[fileCnt][LONG_FILENAME_LENGTH]; + char sortnames[fileCnt][SORTED_LONGNAME_MAXLEN]; #endif // Folder sorting needs 1 bit per entry for flags. @@ -735,7 +731,12 @@ void CardReader::updir() { #endif #else // Copy filenames into the static array - strcpy(sortnames[i], LONGEST_FILENAME); + #if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH + strncpy(sortnames[i], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN); + sortnames[i][SORTED_LONGNAME_MAXLEN - 1] = '\0'; + #else + strncpy(sortnames[i], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN); + #endif #if ENABLED(SDSORT_CACHE_NAMES) strcpy(sortshort[i], filename); #endif @@ -826,12 +827,21 @@ void CardReader::updir() { #if ENABLED(SDSORT_DYNAMIC_RAM) sortnames = new char*[1]; sortnames[0] = strdup(LONGEST_FILENAME); // malloc - sortshort = new char*[1]; - sortshort[0] = strdup(filename); // malloc + #if ENABLED(SDSORT_CACHE_NAMES) + sortshort = new char*[1]; + sortshort[0] = strdup(filename); // malloc + #endif isDir = new uint8_t[1]; #else - strcpy(sortnames[0], LONGEST_FILENAME); - strcpy(sortshort[0], filename); + #if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH + strncpy(sortnames[0], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN); + sortnames[0][SORTED_LONGNAME_MAXLEN - 1] = '\0'; + #else + strncpy(sortnames[0], LONGEST_FILENAME, SORTED_LONGNAME_MAXLEN); + #endif + #if ENABLED(SDSORT_CACHE_NAMES) + strcpy(sortshort[0], filename); + #endif #endif isDir[0] = filenameIsDir ? 0x01 : 0x00; #endif @@ -860,6 +870,16 @@ void CardReader::updir() { #endif // SDCARD_SORT_ALPHA +uint16_t CardReader::get_num_Files() { + return + #if ENABLED(SDCARD_SORT_ALPHA) && SDSORT_USES_RAM && SDSORT_CACHE_NAMES + nrFiles // no need to access the SD card for filenames + #else + getnrfilenames() + #endif + ; +} + void CardReader::printingHasFinished() { stepper.synchronize(); file.close(); @@ -879,6 +899,10 @@ void CardReader::printingHasFinished() { #if ENABLED(SDCARD_SORT_ALPHA) presort(); #endif + + #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) + lcd_reselect_last_file(); + #endif } } diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h index 75674a8e59..5bcdd2b6b0 100644 --- a/Marlin/cardreader.h +++ b/Marlin/cardreader.h @@ -20,8 +20,8 @@ * */ -#ifndef CARDREADER_H -#define CARDREADER_H +#ifndef _CARDREADER_H_ +#define _CARDREADER_H_ #include "MarlinConfig.h" @@ -30,7 +30,6 @@ #define MAX_DIR_DEPTH 10 // Maximum folder depth #include "SdFile.h" - #include "types.h" #include "enum.h" @@ -40,13 +39,15 @@ public: void initsd(); void write_command(char *buf); - //files auto[0-9].g on the sd card are performed in a row - //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset + // Files auto[0-9].g on the sd card are performed in sequence. + // This is to delay autostart and hence the initialisation of + // the sd card to some seconds after the normal init, so the + // device is available soon after a reset. void checkautostart(bool x); - void openFile(char* name, bool read, bool push_current=false); + void openFile(char* name, const bool read, const bool subcall=false); void openLogFile(char* name); - void removeFile(char* name); + void removeFile(const char * const name); void closefile(bool store_location=false); void release(); void openAndPrintFile(const char *name); @@ -66,9 +67,11 @@ public: void ls(); void chdir(const char *relpath); - void updir(); + int8_t updir(); void setroot(); + uint16_t get_num_Files(); + #if ENABLED(SDCARD_SORT_ALPHA) void presort(); void getfilename_sorted(const uint16_t nr); @@ -111,6 +114,12 @@ private: uint8_t sort_order[SDSORT_LIMIT]; #endif + #if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM) + #define SORTED_LONGNAME_MAXLEN ((SDSORT_CACHE_VFATS) * (FILENAME_LENGTH) + 1) + #else + #define SORTED_LONGNAME_MAXLEN LONG_FILENAME_LENGTH + #endif + // Cache filenames to speed up SD menus. #if ENABLED(SDSORT_USES_RAM) @@ -120,10 +129,10 @@ private: char **sortshort, **sortnames; #else char sortshort[SDSORT_LIMIT][FILENAME_LENGTH]; - char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH]; + char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; #endif #elif DISABLED(SDSORT_USES_STACK) - char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH]; + char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN]; #endif // Folder sorting uses an isDir array when caching items. @@ -148,8 +157,7 @@ private: uint8_t file_subcall_ctr; uint32_t filespos[SD_PROCEDURE_DEPTH]; char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; - uint32_t filesize; - uint32_t sdpos; + uint32_t filesize, sdpos; millis_t next_autostart_ms; bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. @@ -164,27 +172,27 @@ private: #endif }; -extern CardReader card; - -#define IS_SD_PRINTING (card.sdprinting) -#define IS_SD_FILE_OPEN (card.isFileOpen()) - #if PIN_EXISTS(SD_DETECT) #if ENABLED(SD_DETECT_INVERTED) - #define IS_SD_INSERTED (READ(SD_DETECT_PIN) != 0) + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == HIGH) #else - #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == 0) + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == LOW) #endif #else - //No card detect line? Assume the card is inserted. + // No card detect line? Assume the card is inserted. #define IS_SD_INSERTED true #endif -#else - -#define IS_SD_PRINTING (false) -#define IS_SD_FILE_OPEN (false) +extern CardReader card; #endif // SDSUPPORT -#endif // __CARDREADER_H +#if ENABLED(SDSUPPORT) + #define IS_SD_PRINTING (card.sdprinting) + #define IS_SD_FILE_OPEN (card.isFileOpen()) +#else + #define IS_SD_PRINTING (false) + #define IS_SD_FILE_OPEN (false) +#endif + +#endif // _CARDREADER_H_ diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 4fa9db910d..aed7add63f 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -36,39 +36,39 @@ * */ -#define EEPROM_VERSION "V41" +#define EEPROM_VERSION "V47" // Change EEPROM version if these are changed: #define EEPROM_OFFSET 100 /** - * V41 EEPROM Layout: + * V47 EEPROM Layout: * * 100 Version (char x4) * 104 EEPROM CRC16 (uint16_t) * * 106 E_STEPPERS (uint8_t) - * 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x8) - * 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x8) - * 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x8) + * 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x8) + 64 + * 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x8) + 64 + * 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x8) + 64 * 155 M204 P planner.acceleration (float) * 159 M204 R planner.retract_acceleration (float) * 163 M204 T planner.travel_acceleration (float) * 167 M205 S planner.min_feedrate_mm_s (float) * 171 M205 T planner.min_travel_feedrate_mm_s (float) - * 175 M205 B planner.min_segment_time (ulong) + * 175 M205 B planner.min_segment_time_us (ulong) * 179 M205 X planner.max_jerk[X_AXIS] (float) * 183 M205 Y planner.max_jerk[Y_AXIS] (float) * 187 M205 Z planner.max_jerk[Z_AXIS] (float) * 191 M205 E planner.max_jerk[E_AXIS] (float) * 195 M206 XYZ home_offset (float x3) - * 207 M218 XYZ hotend_offset (float x3 per additional hotend) + * 207 M218 XYZ hotend_offset (float x3 per additional hotend) +16 * - * Global Leveling: + * Global Leveling: 4 bytes * 219 z_fade_height (float) * * MESH_BED_LEVELING: 43 bytes - * 223 M420 S from mbl.status (bool) + * 223 M420 S planner.leveling_active (bool) * 224 mbl.z_offset (float) * 228 GRID_MAX_POINTS_X (uint8_t) * 229 GRID_MAX_POINTS_Y (uint8_t) @@ -80,90 +80,103 @@ * ABL_PLANAR: 36 bytes * 270 planner.bed_level_matrix (matrix_3x3 = float x9) * - * AUTO_BED_LEVELING_BILINEAR: 47 bytes + * AUTO_BED_LEVELING_BILINEAR: 46 bytes * 306 GRID_MAX_POINTS_X (uint8_t) * 307 GRID_MAX_POINTS_Y (uint8_t) * 308 bilinear_grid_spacing (int x2) * 312 G29 L F bilinear_start (int x2) * 316 z_values[][] (float x9, up to float x256) +988 * - * AUTO_BED_LEVELING_UBL: 6 bytes - * 324 G29 A ubl.state.active (bool) - * 325 G29 Z ubl.state.z_offset (float) - * 329 G29 S ubl.state.storage_slot (int8_t) + * AUTO_BED_LEVELING_UBL: 2 bytes + * 352 G29 A planner.leveling_active (bool) + * 353 G29 S ubl.storage_slot (int8_t) * - * DELTA: 48 bytes - * 348 M666 XYZ endstop_adj (float x3) - * 360 M665 R delta_radius (float) - * 364 M665 L delta_diagonal_rod (float) - * 368 M665 S delta_segments_per_second (float) - * 372 M665 B delta_calibration_radius (float) - * 376 M665 X delta_tower_angle_trim[A] (float) - * 380 M665 Y delta_tower_angle_trim[B] (float) - * 384 M665 Z delta_tower_angle_trim[C] (float) + * DELTA: 44 bytes + * 354 M666 H delta_height (float) + * 358 M666 XYZ delta_endstop_adj (float x3) + * 370 M665 R delta_radius (float) + * 374 M665 L delta_diagonal_rod (float) + * 378 M665 S delta_segments_per_second (float) + * 382 M665 B delta_calibration_radius (float) + * 386 M665 X delta_tower_angle_trim[A] (float) + * 390 M665 Y delta_tower_angle_trim[B] (float) + * 394 M665 Z delta_tower_angle_trim[C] (float) * - * Z_DUAL_ENDSTOPS: 48 bytes - * 348 M666 Z z_endstop_adj (float) - * --- dummy data (float x11) + * [XYZ]_DUAL_ENDSTOPS: 12 bytes + * 354 M666 X x_endstop_adj (float) + * 358 M666 Y y_endstop_adj (float) + * 362 M666 Z z_endstop_adj (float) * * ULTIPANEL: 6 bytes - * 396 M145 S0 H lcd_preheat_hotend_temp (int x2) - * 400 M145 S0 B lcd_preheat_bed_temp (int x2) - * 404 M145 S0 F lcd_preheat_fan_speed (int x2) + * 398 M145 S0 H lcd_preheat_hotend_temp (int x2) + * 402 M145 S0 B lcd_preheat_bed_temp (int x2) + * 406 M145 S0 F lcd_preheat_fan_speed (int x2) * - * PIDTEMP: 66 bytes - * 408 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) - * 424 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) - * 440 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) - * 456 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) - * 472 M301 E4 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) - * 488 M301 L lpq_len (int) + * PIDTEMP: 82 bytes + * 410 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) + * 426 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) + * 442 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) + * 458 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 474 M301 E4 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 490 M301 L lpq_len (int) * * PIDTEMPBED: 12 bytes - * 490 M304 PID thermalManager.bedKp, .bedKi, .bedKd (float x3) + * 492 M304 PID bedKp, .bedKi, .bedKd (float x3) * * DOGLCD: 2 bytes - * 502 M250 C lcd_contrast (uint16_t) + * 504 M250 C lcd_contrast (uint16_t) * * FWRETRACT: 33 bytes - * 504 M209 S autoretract_enabled (bool) - * 505 M207 S retract_length (float) - * 509 M207 F retract_feedrate_mm_s (float) - * 513 M207 Z retract_zlift (float) - * 517 M208 S retract_recover_length (float) - * 521 M208 F retract_recover_feedrate_mm_s (float) - * 525 M207 W swap_retract_length (float) - * 529 M208 W swap_retract_recover_length (float) - * 533 M208 R swap_retract_recover_feedrate_mm_s (float) + * 506 M209 S autoretract_enabled (bool) + * 507 M207 S retract_length (float) + * 511 M207 F retract_feedrate_mm_s (float) + * 515 M207 Z retract_zlift (float) + * 519 M208 S retract_recover_length (float) + * 523 M208 F retract_recover_feedrate_mm_s (float) + * 527 M207 W swap_retract_length (float) + * 531 M208 W swap_retract_recover_length (float) + * 535 M208 R swap_retract_recover_feedrate_mm_s (float) * * Volumetric Extrusion: 21 bytes - * 537 M200 D volumetric_enabled (bool) - * 538 M200 T D filament_size (float x5) (T0..3) + * 539 M200 D parser.volumetric_enabled (bool) + * 540 M200 T D planner.filament_size (float x5) (T0..3) * - * HAVE_TMC2130: 20 bytes - * 558 M906 X Stepper X current (uint16_t) - * 560 M906 Y Stepper Y current (uint16_t) - * 562 M906 Z Stepper Z current (uint16_t) - * 564 M906 X2 Stepper X2 current (uint16_t) - * 566 M906 Y2 Stepper Y2 current (uint16_t) - * 568 M906 Z2 Stepper Z2 current (uint16_t) - * 570 M906 E0 Stepper E0 current (uint16_t) - * 572 M906 E1 Stepper E1 current (uint16_t) - * 574 M906 E2 Stepper E2 current (uint16_t) - * 576 M906 E3 Stepper E3 current (uint16_t) + * HAVE_TMC2130 || HAVE_TMC2208: 22 bytes + * 560 M906 X Stepper X current (uint16_t) + * 562 M906 Y Stepper Y current (uint16_t) + * 564 M906 Z Stepper Z current (uint16_t) + * 566 M906 X2 Stepper X2 current (uint16_t) + * 568 M906 Y2 Stepper Y2 current (uint16_t) + * 570 M906 Z2 Stepper Z2 current (uint16_t) + * 572 M906 E0 Stepper E0 current (uint16_t) + * 574 M906 E1 Stepper E1 current (uint16_t) + * 576 M906 E2 Stepper E2 current (uint16_t) + * 578 M906 E3 Stepper E3 current (uint16_t) * 580 M906 E4 Stepper E4 current (uint16_t) * + * SENSORLESS HOMING 4 bytes + * 582 M914 X Stepper X and X2 threshold (int16_t) + * 584 M914 Y Stepper Y and Y2 threshold (int16_t) + * * LIN_ADVANCE: 8 bytes - * 584 M900 K extruder_advance_k (float) - * 588 M900 WHD advance_ed_ratio (float) + * 586 M900 K extruder_advance_k (float) + * 590 M900 WHD advance_ed_ratio (float) * * HAS_MOTOR_CURRENT_PWM: - * 592 M907 X Stepper XY current (uint32_t) - * 596 M907 Z Stepper Z current (uint32_t) - * 600 M907 E Stepper E current (uint32_t) + * 594 M907 X Stepper XY current (uint32_t) + * 598 M907 Z Stepper Z current (uint32_t) + * 602 M907 E Stepper E current (uint32_t) * - * 604 Minimum end-point - * 1925 (604 + 36 + 9 + 288 + 988) Maximum end-point + * CNC_COORDINATE_SYSTEMS 108 bytes + * 606 G54-G59.3 coordinate_system (float x 27) + * + * SKEW_CORRECTION: 12 bytes + * 714 M852 I planner.xy_skew_factor (float) + * 718 M852 J planner.xz_skew_factor (float) + * 722 M852 K planner.yz_skew_factor (float) + * + * 726 Minimum end-point + * 2255 (726 + 208 + 36 + 9 + 288 + 988) Maximum end-point * * ======================================================================== * meshes_begin (between max and min end-point, directly above) @@ -184,16 +197,13 @@ MarlinSettings settings; #include "temperature.h" #include "ultralcd.h" #include "stepper.h" - -#if ENABLED(INCH_MODE_SUPPORT) || (ENABLED(ULTIPANEL) && ENABLED(TEMPERATURE_UNITS_SUPPORT)) - #include "gcode.h" -#endif +#include "gcode.h" #if ENABLED(MESH_BED_LEVELING) #include "mesh_bed_leveling.h" #endif -#if ENABLED(HAVE_TMC2130) +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) #include "stepper_indirection.h" #endif @@ -205,28 +215,32 @@ MarlinSettings settings; extern void refresh_bed_level(); #endif +#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + float new_z_fade_height; +#endif + /** * Post-process after Retrieve or Reset */ void MarlinSettings::postprocess() { + const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; + // steps per s2 needs to be updated to agree with units per s2 planner.reset_acceleration_rates(); // Make sure delta kinematics are updated before refreshing the // planner position so the stepper counts will be set correctly. #if ENABLED(DELTA) - recalc_delta_settings(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); + recalc_delta_settings(); #endif - // Refresh steps_to_mm with the reciprocal of axis_steps_per_mm - // and init stepper.count[], planner.position[] with current_position - planner.refresh_positioning(); - #if ENABLED(PIDTEMP) thermalManager.updatePID(); #endif - calculate_volumetric_multipliers(); + #if DISABLED(NO_VOLUMETRICS) + planner.calculate_volumetric_multipliers(); + #endif #if HAS_HOME_OFFSET || ENABLED(DUAL_X_CARRIAGE) // Software endstops depend on home_offset @@ -234,11 +248,7 @@ void MarlinSettings::postprocess() { #endif #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - set_z_fade_height(planner.z_fade_height); - #endif - - #if HAS_BED_PROBE - refresh_zprobe_zoffset(); + set_z_fade_height(new_z_fade_height, false); // false = no report #endif #if ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -249,6 +259,14 @@ void MarlinSettings::postprocess() { #if HAS_MOTOR_CURRENT_PWM stepper.refresh_motor_power(); #endif + + // Refresh steps_to_mm with the reciprocal of axis_steps_per_mm + // and init stepper.count[], planner.position[] with current_position + planner.refresh_positioning(); + + // Various factors can change the current position + if (memcmp(oldpos, current_position, sizeof(oldpos))) + report_current_position(); } #if ENABLED(EEPROM_SETTINGS) @@ -331,20 +349,12 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(planner.travel_acceleration); EEPROM_WRITE(planner.min_feedrate_mm_s); EEPROM_WRITE(planner.min_travel_feedrate_mm_s); - EEPROM_WRITE(planner.min_segment_time); + EEPROM_WRITE(planner.min_segment_time_us); EEPROM_WRITE(planner.max_jerk); #if !HAS_HOME_OFFSET const float home_offset[XYZ] = { 0 }; #endif - #if ENABLED(DELTA) - dummy = 0.0; - EEPROM_WRITE(dummy); - EEPROM_WRITE(dummy); - dummy = DELTA_HEIGHT + home_offset[Z_AXIS]; - EEPROM_WRITE(dummy); - #else - EEPROM_WRITE(home_offset); - #endif + EEPROM_WRITE(home_offset); #if HOTENDS > 1 // Skip hotend 0 which must be 0 @@ -373,7 +383,7 @@ void MarlinSettings::postprocess() { sizeof(mbl.z_values) == GRID_MAX_POINTS * sizeof(mbl.z_values[0][0]), "MBL Z array is the wrong size." ); - const bool leveling_is_on = TEST(mbl.status, MBL_STATUS_HAS_MESH_BIT); + const bool leveling_is_on = mbl.has_mesh; const uint8_t mesh_num_x = GRID_MAX_POINTS_X, mesh_num_y = GRID_MAX_POINTS_Y; EEPROM_WRITE(leveling_is_on); EEPROM_WRITE(mbl.z_offset); @@ -436,35 +446,51 @@ void MarlinSettings::postprocess() { #endif // AUTO_BED_LEVELING_BILINEAR #if ENABLED(AUTO_BED_LEVELING_UBL) - EEPROM_WRITE(ubl.state.active); - EEPROM_WRITE(ubl.state.z_offset); - EEPROM_WRITE(ubl.state.storage_slot); + EEPROM_WRITE(planner.leveling_active); + EEPROM_WRITE(ubl.storage_slot); #else const bool ubl_active = false; - dummy = 0.0f; const int8_t storage_slot = -1; EEPROM_WRITE(ubl_active); - EEPROM_WRITE(dummy); EEPROM_WRITE(storage_slot); #endif // AUTO_BED_LEVELING_UBL - // 10 floats for DELTA / Z_DUAL_ENDSTOPS + // 11 floats for DELTA / [XYZ]_DUAL_ENDSTOPS #if ENABLED(DELTA) - EEPROM_WRITE(endstop_adj); // 3 floats + EEPROM_WRITE(delta_height); // 1 float + EEPROM_WRITE(delta_endstop_adj); // 3 floats EEPROM_WRITE(delta_radius); // 1 float EEPROM_WRITE(delta_diagonal_rod); // 1 float EEPROM_WRITE(delta_segments_per_second); // 1 float EEPROM_WRITE(delta_calibration_radius); // 1 float EEPROM_WRITE(delta_tower_angle_trim); // 3 floats + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + // Write dual endstops in X, Y, Z order. Unused = 0.0 dummy = 0.0f; - for (uint8_t q = 2; q--;) EEPROM_WRITE(dummy); - #elif ENABLED(Z_DUAL_ENDSTOPS) - EEPROM_WRITE(z_endstop_adj); // 1 float - dummy = 0.0f; - for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy); + #if ENABLED(X_DUAL_ENDSTOPS) + EEPROM_WRITE(x_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_WRITE(y_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_WRITE(z_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + for (uint8_t q = 8; q--;) EEPROM_WRITE(dummy); + #else dummy = 0.0f; - for (uint8_t q = 12; q--;) EEPROM_WRITE(dummy); + for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy); #endif #if DISABLED(ULTIPANEL) @@ -542,78 +568,85 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(swap_retract_recover_length); EEPROM_WRITE(swap_retract_recover_feedrate_mm_s); - EEPROM_WRITE(volumetric_enabled); + // + // Volumetric & Filament Size + // + #if DISABLED(NO_VOLUMETRICS) - // Save filament sizes - for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { - if (q < COUNT(filament_size)) dummy = filament_size[q]; - EEPROM_WRITE(dummy); - } + EEPROM_WRITE(parser.volumetric_enabled); - // Save TMC2130 Configuration, and placeholder values + // Save filament sizes + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + if (q < COUNT(planner.filament_size)) dummy = planner.filament_size[q]; + EEPROM_WRITE(dummy); + } + + #endif // !NO_VOLUMETRICS + + // Save TMC2130 or TMC2208 Configuration, and placeholder values uint16_t val; - #if ENABLED(HAVE_TMC2130) - #if ENABLED(X_IS_TMC2130) + #if HAS_TRINAMIC + #if X_IS_TRINAMIC val = stepperX.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(Y_IS_TMC2130) + #if Y_IS_TRINAMIC val = stepperY.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(Z_IS_TMC2130) + #if Z_IS_TRINAMIC val = stepperZ.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(X2_IS_TMC2130) + #if X2_IS_TRINAMIC val = stepperX2.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(Y2_IS_TMC2130) + #if Y2_IS_TRINAMIC val = stepperY2.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(Z2_IS_TMC2130) + #if Z2_IS_TRINAMIC val = stepperZ2.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(E0_IS_TMC2130) + #if E0_IS_TRINAMIC val = stepperE0.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(E1_IS_TMC2130) + #if E1_IS_TRINAMIC val = stepperE1.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(E2_IS_TMC2130) + #if E2_IS_TRINAMIC val = stepperE2.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(E3_IS_TMC2130) + #if E3_IS_TRINAMIC val = stepperE3.getCurrent(); #else val = 0; #endif EEPROM_WRITE(val); - #if ENABLED(E4_IS_TMC2130) + #if E4_IS_TRINAMIC val = stepperE4.getCurrent(); #else val = 0; @@ -624,6 +657,28 @@ void MarlinSettings::postprocess() { for (uint8_t q = 11; q--;) EEPROM_WRITE(val); #endif + // + // TMC2130 Sensorless homing threshold + // + int16_t thrs; + #if ENABLED(SENSORLESS_HOMING) + #if ENABLED(X_IS_TMC2130) + thrs = stepperX.sgt(); + #else + thrs = 0; + #endif + EEPROM_WRITE(thrs); + #if ENABLED(Y_IS_TMC2130) + thrs = stepperY.sgt(); + #else + thrs = 0; + #endif + EEPROM_WRITE(thrs); + #else + thrs = 0; + for (uint8_t q = 2; q--;) EEPROM_WRITE(thrs); + #endif + // // Linear Advance // @@ -644,6 +699,30 @@ void MarlinSettings::postprocess() { for (uint8_t q = 3; q--;) EEPROM_WRITE(dummyui32); #endif + // + // CNC Coordinate Systems + // + + #if ENABLED(CNC_COORDINATE_SYSTEMS) + EEPROM_WRITE(coordinate_system); // 27 floats + #else + dummy = 0.0f; + for (uint8_t q = 27; q--;) EEPROM_WRITE(dummy); + #endif + + // + // Skew correction factors + // + + #if ENABLED(SKEW_CORRECTION) + EEPROM_WRITE(planner.xy_skew_factor); + EEPROM_WRITE(planner.xz_skew_factor); + EEPROM_WRITE(planner.yz_skew_factor); + #else + dummy = 0.0f; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); + #endif + if (!eeprom_error) { const int eeprom_size = eeprom_index; @@ -665,8 +744,8 @@ void MarlinSettings::postprocess() { } #if ENABLED(UBL_SAVE_ACTIVE_ON_M500) - if (ubl.state.storage_slot >= 0) - store_mesh(ubl.state.storage_slot); + if (ubl.storage_slot >= 0) + store_mesh(ubl.storage_slot); #endif return !eeprom_error; @@ -702,14 +781,20 @@ void MarlinSettings::postprocess() { } else { float dummy = 0; - bool dummyb; + #if DISABLED(AUTO_BED_LEVELING_UBL) || DISABLED(FWRETRACT) + bool dummyb; + #endif - working_crc = 0; //clear before reading first "real data" + working_crc = 0; // Init to 0. Accumulated by EEPROM_READ // Number of esteppers may change uint8_t esteppers; EEPROM_READ(esteppers); + // + // Planner Motion + // + // Get only the number of E stepper parameters previously stored // Any steppers added later are set to their defaults const float def1[] = DEFAULT_AXIS_STEPS_PER_UNIT, def2[] = DEFAULT_MAX_FEEDRATE; @@ -730,19 +815,21 @@ void MarlinSettings::postprocess() { EEPROM_READ(planner.travel_acceleration); EEPROM_READ(planner.min_feedrate_mm_s); EEPROM_READ(planner.min_travel_feedrate_mm_s); - EEPROM_READ(planner.min_segment_time); + EEPROM_READ(planner.min_segment_time_us); EEPROM_READ(planner.max_jerk); + // + // Home Offset (M206) + // + #if !HAS_HOME_OFFSET float home_offset[XYZ]; #endif EEPROM_READ(home_offset); - #if ENABLED(DELTA) - home_offset[X_AXIS] = 0.0; - home_offset[Y_AXIS] = 0.0; - home_offset[Z_AXIS] -= DELTA_HEIGHT; - #endif + // + // Hotend Offsets, if any + // #if HOTENDS > 1 // Skip hotend 0 which must be 0 @@ -755,7 +842,7 @@ void MarlinSettings::postprocess() { // #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - EEPROM_READ(planner.z_fade_height); + EEPROM_READ(new_z_fade_height); #else EEPROM_READ(dummy); #endif @@ -772,7 +859,7 @@ void MarlinSettings::postprocess() { EEPROM_READ(mesh_num_y); #if ENABLED(MESH_BED_LEVELING) - mbl.status = leveling_is_on ? _BV(MBL_STATUS_HAS_MESH_BIT) : 0; + mbl.has_mesh = leveling_is_on; mbl.z_offset = dummy; if (mesh_num_x == GRID_MAX_POINTS_X && mesh_num_y == GRID_MAX_POINTS_Y) { // EEPROM data fits the current mesh @@ -827,48 +914,78 @@ void MarlinSettings::postprocess() { for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy); } + // + // Unified Bed Leveling active state + // + #if ENABLED(AUTO_BED_LEVELING_UBL) - EEPROM_READ(ubl.state.active); - EEPROM_READ(ubl.state.z_offset); - EEPROM_READ(ubl.state.storage_slot); + EEPROM_READ(planner.leveling_active); + EEPROM_READ(ubl.storage_slot); #else uint8_t dummyui8; EEPROM_READ(dummyb); - EEPROM_READ(dummy); EEPROM_READ(dummyui8); #endif // AUTO_BED_LEVELING_UBL + // + // DELTA Geometry or Dual Endstops offsets + // + #if ENABLED(DELTA) - EEPROM_READ(endstop_adj); // 3 floats + EEPROM_READ(delta_height); // 1 float + EEPROM_READ(delta_endstop_adj); // 3 floats EEPROM_READ(delta_radius); // 1 float EEPROM_READ(delta_diagonal_rod); // 1 float EEPROM_READ(delta_segments_per_second); // 1 float EEPROM_READ(delta_calibration_radius); // 1 float EEPROM_READ(delta_tower_angle_trim); // 3 floats - dummy = 0.0f; - for (uint8_t q=2; q--;) EEPROM_READ(dummy); - #elif ENABLED(Z_DUAL_ENDSTOPS) - EEPROM_READ(z_endstop_adj); - dummy = 0.0f; - for (uint8_t q=11; q--;) EEPROM_READ(dummy); + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + + #if ENABLED(X_DUAL_ENDSTOPS) + EEPROM_READ(x_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_READ(y_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_READ(z_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + + for (uint8_t q=8; q--;) EEPROM_READ(dummy); + #else - dummy = 0.0f; - for (uint8_t q=12; q--;) EEPROM_READ(dummy); + + for (uint8_t q=11; q--;) EEPROM_READ(dummy); + #endif + // + // LCD Preheat settings + // + #if DISABLED(ULTIPANEL) int lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2]; #endif - - EEPROM_READ(lcd_preheat_hotend_temp); - EEPROM_READ(lcd_preheat_bed_temp); - EEPROM_READ(lcd_preheat_fan_speed); + EEPROM_READ(lcd_preheat_hotend_temp); // 2 floats + EEPROM_READ(lcd_preheat_bed_temp); // 2 floats + EEPROM_READ(lcd_preheat_fan_speed); // 2 floats //EEPROM_ASSERT( // WITHIN(lcd_preheat_fan_speed, 0, 255), // "lcd_preheat_fan_speed out of range" //); + // + // Hotend PID + // + #if ENABLED(PIDTEMP) for (uint8_t e = 0; e < MAX_EXTRUDERS; e++) { EEPROM_READ(dummy); // Kp @@ -892,11 +1009,19 @@ void MarlinSettings::postprocess() { for (uint8_t q = MAX_EXTRUDERS * 4; q--;) EEPROM_READ(dummy); // Kp, Ki, Kd, Kc #endif // !PIDTEMP + // + // PID Extrusion Scaling + // + #if DISABLED(PID_EXTRUSION_SCALING) int lpq_len; #endif EEPROM_READ(lpq_len); + // + // Heated Bed PID + // + #if ENABLED(PIDTEMPBED) EEPROM_READ(dummy); // bedKp if (dummy != DUMMY_PID_VALUE) { @@ -908,11 +1033,19 @@ void MarlinSettings::postprocess() { for (uint8_t q=3; q--;) EEPROM_READ(dummy); // bedKp, bedKi, bedKd #endif + // + // LCD Contrast + // + #if !HAS_LCD_CONTRAST uint16_t lcd_contrast; #endif EEPROM_READ(lcd_contrast); + // + // Firmware Retraction + // + #if ENABLED(FWRETRACT) EEPROM_READ(autoretract_enabled); EEPROM_READ(retract_length); @@ -928,61 +1061,97 @@ void MarlinSettings::postprocess() { for (uint8_t q=8; q--;) EEPROM_READ(dummy); #endif - EEPROM_READ(volumetric_enabled); + // + // Volumetric & Filament Size + // + #if DISABLED(NO_VOLUMETRICS) - for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { - EEPROM_READ(dummy); - if (q < COUNT(filament_size)) filament_size[q] = dummy; - } + EEPROM_READ(parser.volumetric_enabled); + + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + EEPROM_READ(dummy); + if (q < COUNT(planner.filament_size)) planner.filament_size[q] = dummy; + } + + #endif + + // + // TMC2130 Stepper Current + // uint16_t val; - #if ENABLED(HAVE_TMC2130) + #if HAS_TRINAMIC EEPROM_READ(val); - #if ENABLED(X_IS_TMC2130) + #if X_IS_TRINAMIC stepperX.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(Y_IS_TMC2130) + #if Y_IS_TRINAMIC stepperY.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(Z_IS_TMC2130) + #if Z_IS_TRINAMIC stepperZ.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(X2_IS_TMC2130) + #if X2_IS_TRINAMIC stepperX2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(Y2_IS_TMC2130) + #if Y2_IS_TRINAMIC stepperY2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(Z2_IS_TMC2130) + #if Z2_IS_TRINAMIC stepperZ2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(E0_IS_TMC2130) + #if E0_IS_TRINAMIC stepperE0.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(E1_IS_TMC2130) + #if E1_IS_TRINAMIC stepperE1.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(E2_IS_TMC2130) + #if E2_IS_TRINAMIC stepperE2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(E3_IS_TMC2130) + #if E3_IS_TRINAMIC stepperE3.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif EEPROM_READ(val); - #if ENABLED(E4_IS_TMC2130) + #if E4_IS_TRINAMIC stepperE4.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); #endif #else - for (uint8_t q = 0; q < 11; q++) EEPROM_READ(val); + for (uint8_t q = 11; q--;) EEPROM_READ(val); + #endif + + /* + * TMC2130 Sensorless homing threshold. + * X and X2 use the same value + * Y and Y2 use the same value + */ + int16_t thrs; + #if ENABLED(SENSORLESS_HOMING) + EEPROM_READ(thrs); + #if ENABLED(X_IS_TMC2130) + stepperX.sgt(thrs); + #endif + #if ENABLED(X2_IS_TMC2130) + stepperX2.sgt(thrs); + #endif + EEPROM_READ(thrs); + #if ENABLED(Y_IS_TMC2130) + stepperY.sgt(thrs); + #endif + #if ENABLED(Y2_IS_TMC2130) + stepperY2.sgt(thrs); + #endif + #else + for (uint8_t q = 0; q < 2; q++) EEPROM_READ(thrs); #endif // @@ -997,6 +1166,10 @@ void MarlinSettings::postprocess() { EEPROM_READ(dummy); #endif + // + // Motor Current PWM + // + #if HAS_MOTOR_CURRENT_PWM for (uint8_t q = 3; q--;) EEPROM_READ(stepper.motor_current_setting[q]); #else @@ -1004,6 +1177,34 @@ void MarlinSettings::postprocess() { for (uint8_t q = 3; q--;) EEPROM_READ(dummyui32); #endif + // + // CNC Coordinate System + // + + #if ENABLED(CNC_COORDINATE_SYSTEMS) + (void)select_coordinate_system(-1); // Go back to machine space + EEPROM_READ(coordinate_system); // 27 floats + #else + for (uint8_t q = 27; q--;) EEPROM_READ(dummy); + #endif + + // + // Skew correction factors + // + + #if ENABLED(SKEW_CORRECTION_GCODE) + EEPROM_READ(planner.xy_skew_factor); + #if ENABLED(SKEW_CORRECTION_FOR_Z) + EEPROM_READ(planner.xz_skew_factor); + EEPROM_READ(planner.yz_skew_factor); + #else + EEPROM_READ(dummy); + EEPROM_READ(dummy); + #endif + #else + for (uint8_t q = 3; q--;) EEPROM_READ(dummy); + #endif + if (working_crc == stored_crc) { postprocess(); #if ENABLED(EEPROM_CHITCHAT) @@ -1048,10 +1249,10 @@ void MarlinSettings::postprocess() { ubl.reset(); } - if (ubl.state.storage_slot >= 0) { - load_mesh(ubl.state.storage_slot); + if (ubl.storage_slot >= 0) { + load_mesh(ubl.storage_slot); #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHOPAIR("Mesh ", ubl.state.storage_slot); + SERIAL_ECHOPAIR("Mesh ", ubl.storage_slot); SERIAL_ECHOLNPGM(" loaded from storage."); #endif } @@ -1184,7 +1385,7 @@ void MarlinSettings::reset() { planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION; planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION; planner.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE; - planner.min_segment_time = DEFAULT_MINSEGMENTTIME; + planner.min_segment_time_us = DEFAULT_MINSEGMENTTIME; planner.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE; planner.max_jerk[X_AXIS] = DEFAULT_XJERK; planner.max_jerk[Y_AXIS] = DEFAULT_YJERK; @@ -1192,7 +1393,7 @@ void MarlinSettings::reset() { planner.max_jerk[E_AXIS] = DEFAULT_EJERK; #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - planner.z_fade_height = 0.0; + new_z_fade_height = 10.0; #endif #if HAS_HOME_OFFSET @@ -1228,23 +1429,43 @@ void MarlinSettings::reset() { #if ENABLED(DELTA) const float adj[ABC] = DELTA_ENDSTOP_ADJ, dta[ABC] = DELTA_TOWER_ANGLE_TRIM; - COPY(endstop_adj, adj); + delta_height = DELTA_HEIGHT; + COPY(delta_endstop_adj, adj); delta_radius = DELTA_RADIUS; delta_diagonal_rod = DELTA_DIAGONAL_ROD; delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; delta_calibration_radius = DELTA_CALIBRATION_RADIUS; COPY(delta_tower_angle_trim, dta); - home_offset[Z_AXIS] = 0; - #elif ENABLED(Z_DUAL_ENDSTOPS) + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) - z_endstop_adj = - #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT - Z_DUAL_ENDSTOPS_ADJUSTMENT - #else - 0 - #endif - ; + #if ENABLED(X_DUAL_ENDSTOPS) + x_endstop_adj = ( + #ifdef X_DUAL_ENDSTOPS_ADJUSTMENT + X_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + y_endstop_adj = ( + #ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT + Y_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + z_endstop_adj = ( + #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT + Z_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif #endif @@ -1296,15 +1517,19 @@ void MarlinSettings::reset() { swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; #endif // FWRETRACT - volumetric_enabled = - #if ENABLED(VOLUMETRIC_DEFAULT_ON) - true - #else - false - #endif - ; - for (uint8_t q = 0; q < COUNT(filament_size); q++) - filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; + #if DISABLED(NO_VOLUMETRICS) + + parser.volumetric_enabled = + #if ENABLED(VOLUMETRIC_DEFAULT_ON) + true + #else + false + #endif + ; + for (uint8_t q = 0; q < COUNT(planner.filament_size); q++) + planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; + + #endif endstops.enable_globally( #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) @@ -1314,36 +1539,52 @@ void MarlinSettings::reset() { #endif ); - #if ENABLED(HAVE_TMC2130) + #if X_IS_TRINAMIC + stepperX.setCurrent(X_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if Y_IS_TRINAMIC + stepperY.setCurrent(Y_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if Z_IS_TRINAMIC + stepperZ.setCurrent(Z_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if X2_IS_TRINAMIC + stepperX2.setCurrent(X2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if Y2_IS_TRINAMIC + stepperY2.setCurrent(Y2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if Z2_IS_TRINAMIC + stepperZ2.setCurrent(Z2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if E0_IS_TRINAMIC + stepperE0.setCurrent(E0_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if E1_IS_TRINAMIC + stepperE1.setCurrent(E1_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if E2_IS_TRINAMIC + stepperE2.setCurrent(E2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if E3_IS_TRINAMIC + stepperE3.setCurrent(E3_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if E4_IS_TRINAMIC + stepperE4.setCurrent(E4_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + + #if ENABLED(SENSORLESS_HOMING) #if ENABLED(X_IS_TMC2130) - stepperX.setCurrent(X_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(Y_IS_TMC2130) - stepperY.setCurrent(Y_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(Z_IS_TMC2130) - stepperZ.setCurrent(Z_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperX.sgt(X_HOMING_SENSITIVITY); #endif #if ENABLED(X2_IS_TMC2130) - stepperX2.setCurrent(X2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperX2.sgt(X_HOMING_SENSITIVITY); + #endif + #if ENABLED(Y_IS_TMC2130) + stepperY.sgt(Y_HOMING_SENSITIVITY); #endif #if ENABLED(Y2_IS_TMC2130) - stepperY2.setCurrent(Y2_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(Z2_IS_TMC2130) - stepperZ2.setCurrent(Z2_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(E0_IS_TMC2130) - stepperE0.setCurrent(E0_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(E1_IS_TMC2130) - stepperE1.setCurrent(E1_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(E2_IS_TMC2130) - stepperE2.setCurrent(E2_CURRENT, R_SENSE, HOLD_MULTIPLIER); - #endif - #if ENABLED(E3_IS_TMC2130) - stepperE3.setCurrent(E3_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperY2.sgt(Y_HOMING_SENSITIVITY); #endif #endif @@ -1362,6 +1603,14 @@ void MarlinSettings::reset() { ubl.reset(); #endif + #if ENABLED(SKEW_CORRECTION_GCODE) + planner.xy_skew_factor = XY_SKEW_FACTOR; + #if ENABLED(SKEW_CORRECTION_FOR_Z) + planner.xz_skew_factor = XZ_SKEW_FACTOR; + planner.yz_skew_factor = YZ_SKEW_FACTOR; + #endif + #endif + postprocess(); #if ENABLED(EEPROM_CHITCHAT) @@ -1379,22 +1628,22 @@ void MarlinSettings::reset() { * * Unless specifically disabled, M503 is available even without EEPROM */ - void MarlinSettings::report(bool forReplay) { + void MarlinSettings::report(const bool forReplay) { /** * Announce current units, in case inches are being displayed */ CONFIG_ECHO_START; #if ENABLED(INCH_MODE_SUPPORT) - #define LINEAR_UNIT(N) ((N) / parser.linear_unit_factor) - #define VOLUMETRIC_UNIT(N) ((N) / (volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) + #define LINEAR_UNIT(N) (float(N) / parser.linear_unit_factor) + #define VOLUMETRIC_UNIT(N) (float(N) / (parser.volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) SERIAL_ECHOPGM(" G2"); SERIAL_CHAR(parser.linear_unit_factor == 1.0 ? '1' : '0'); SERIAL_ECHOPGM(" ; Units in "); serialprintPGM(parser.linear_unit_factor == 1.0 ? PSTR("mm\n") : PSTR("inches\n")); #else - #define LINEAR_UNIT(N) N - #define VOLUMETRIC_UNIT(N) N + #define LINEAR_UNIT(N) (N) + #define VOLUMETRIC_UNIT(N) (N) SERIAL_ECHOLNPGM(" G21 ; Units in mm"); #endif @@ -1410,7 +1659,7 @@ void MarlinSettings::reset() { SERIAL_ECHOPGM(" ; Units in "); serialprintPGM(parser.temp_units_name()); #else - #define TEMP_UNIT(N) N + #define TEMP_UNIT(N) (N) SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius"); #endif @@ -1418,46 +1667,50 @@ void MarlinSettings::reset() { SERIAL_EOL(); - /** - * Volumetric extrusion M200 - */ - if (!forReplay) { - CONFIG_ECHO_START; - SERIAL_ECHOPGM("Filament settings:"); - if (volumetric_enabled) - SERIAL_EOL(); - else - SERIAL_ECHOLNPGM(" Disabled"); - } + #if DISABLED(NO_VOLUMETRICS) - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 D", filament_size[0]); - SERIAL_EOL(); - #if EXTRUDERS > 1 - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T1 D", filament_size[1]); - SERIAL_EOL(); - #if EXTRUDERS > 2 + /** + * Volumetric extrusion M200 + */ + if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T2 D", filament_size[2]); - SERIAL_EOL(); - #if EXTRUDERS > 3 - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T3 D", filament_size[3]); + SERIAL_ECHOPGM("Filament settings:"); + if (parser.volumetric_enabled) SERIAL_EOL(); - #if EXTRUDERS > 4 - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T4 D", filament_size[4]); - SERIAL_EOL(); - #endif // EXTRUDERS > 4 - #endif // EXTRUDERS > 3 - #endif // EXTRUDERS > 2 - #endif // EXTRUDERS > 1 + else + SERIAL_ECHOLNPGM(" Disabled"); + } - if (!volumetric_enabled) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM(" M200 D0"); - } + SERIAL_ECHOPAIR(" M200 D", LINEAR_UNIT(planner.filament_size[0])); + SERIAL_EOL(); + #if EXTRUDERS > 1 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T1 D", LINEAR_UNIT(planner.filament_size[1])); + SERIAL_EOL(); + #if EXTRUDERS > 2 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T2 D", LINEAR_UNIT(planner.filament_size[2])); + SERIAL_EOL(); + #if EXTRUDERS > 3 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T3 D", LINEAR_UNIT(planner.filament_size[3])); + SERIAL_EOL(); + #if EXTRUDERS > 4 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T4 D", LINEAR_UNIT(planner.filament_size[4])); + SERIAL_EOL(); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + + if (!parser.volumetric_enabled) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM(" M200 D0"); + } + + #endif if (!forReplay) { CONFIG_ECHO_START; @@ -1530,12 +1783,12 @@ void MarlinSettings::reset() { if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Advanced: S T B X Z E"); + SERIAL_ECHOLNPGM("Advanced: S T B X Z E"); } CONFIG_ECHO_START; SERIAL_ECHOPAIR(" M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s)); SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); - SERIAL_ECHOPAIR(" B", planner.min_segment_time); + SERIAL_ECHOPAIR(" B", planner.min_segment_time_us); SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS])); SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS])); SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS])); @@ -1569,71 +1822,68 @@ void MarlinSettings::reset() { } #endif - #if ENABLED(MESH_BED_LEVELING) + /** + * Bed Leveling + */ + #if HAS_LEVELING - if (!forReplay) { - CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Mesh Bed Leveling:"); - } - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M420 S", leveling_is_valid() ? 1 : 0); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.z_fade_height)); - #endif - SERIAL_EOL(); - for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) { - for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) { + #if ENABLED(MESH_BED_LEVELING) + + if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" G29 S3 X", (int)px + 1); - SERIAL_ECHOPAIR(" Y", (int)py + 1); - SERIAL_ECHOPGM(" Z"); - SERIAL_PROTOCOL_F(LINEAR_UNIT(mbl.z_values[px][py]), 5); - SERIAL_EOL(); + SERIAL_ECHOLNPGM("Mesh Bed Leveling:"); } - } - #elif ENABLED(AUTO_BED_LEVELING_UBL) + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + if (!forReplay) { + CONFIG_ECHO_START; + ubl.echo_name(); + SERIAL_ECHOLNPGM(":"); + } + + #elif HAS_ABL + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Auto Bed Leveling:"); + } - if (!forReplay) { - CONFIG_ECHO_START; - ubl.echo_name(); - SERIAL_ECHOLNPGM(":"); - } - CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M420 S", leveling_is_active() ? 1 : 0); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - SERIAL_ECHOPAIR(" Z", planner.z_fade_height); #endif - SERIAL_EOL(); - if (!forReplay) { - SERIAL_EOL(); - ubl.report_state(); - - SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.state.storage_slot); - - SERIAL_ECHOPGM("z_offset: "); - SERIAL_ECHO_F(ubl.state.z_offset, 6); - SERIAL_EOL(); - - SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes()); - SERIAL_ECHOLNPGM(" meshes.\n"); - } - - #elif HAS_ABL - - if (!forReplay) { - CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Auto Bed Leveling:"); - } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M420 S", leveling_is_active() ? 1 : 0); + SERIAL_ECHOPAIR(" M420 S", planner.leveling_active ? 1 : 0); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.z_fade_height)); #endif SERIAL_EOL(); - #endif + #if ENABLED(MESH_BED_LEVELING) + + for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) { + for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" G29 S3 X", (int)px + 1); + SERIAL_ECHOPAIR(" Y", (int)py + 1); + SERIAL_ECHOPGM(" Z"); + SERIAL_PROTOCOL_F(LINEAR_UNIT(mbl.z_values[px][py]), 5); + SERIAL_EOL(); + } + } + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + if (!forReplay) { + SERIAL_EOL(); + ubl.report_state(); + SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.storage_slot); + SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes()); + SERIAL_ECHOLNPGM(" meshes.\n"); + } + + #endif + + #endif // HAS_LEVELING #if ENABLED(DELTA) if (!forReplay) { @@ -1641,9 +1891,9 @@ void MarlinSettings::reset() { SERIAL_ECHOLNPGM("Endstop adjustment:"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M666 X", LINEAR_UNIT(endstop_adj[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(endstop_adj[Y_AXIS])); - SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(endstop_adj[Z_AXIS])); + SERIAL_ECHOPAIR(" M666 X", LINEAR_UNIT(delta_endstop_adj[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_endstop_adj[Y_AXIS])); + SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(delta_endstop_adj[Z_AXIS])); if (!forReplay) { CONFIG_ECHO_START; SERIAL_ECHOLNPGM("Delta settings: L R H S B XYZ"); @@ -1651,20 +1901,31 @@ void MarlinSettings::reset() { CONFIG_ECHO_START; SERIAL_ECHOPAIR(" M665 L", LINEAR_UNIT(delta_diagonal_rod)); SERIAL_ECHOPAIR(" R", LINEAR_UNIT(delta_radius)); - SERIAL_ECHOPAIR(" H", LINEAR_UNIT(DELTA_HEIGHT + home_offset[Z_AXIS])); + SERIAL_ECHOPAIR(" H", LINEAR_UNIT(delta_height)); SERIAL_ECHOPAIR(" S", delta_segments_per_second); SERIAL_ECHOPAIR(" B", LINEAR_UNIT(delta_calibration_radius)); SERIAL_ECHOPAIR(" X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS])); SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); SERIAL_EOL(); - #elif ENABLED(Z_DUAL_ENDSTOPS) + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Z2 Endstop adjustment:"); + SERIAL_ECHOLNPGM("Endstop adjustment:"); } CONFIG_ECHO_START; - SERIAL_ECHOLNPAIR(" M666 Z", LINEAR_UNIT(z_endstop_adj)); + SERIAL_ECHOPGM(" M666"); + #if ENABLED(X_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(x_endstop_adj)); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(y_endstop_adj)); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(z_endstop_adj)); + #endif + SERIAL_EOL(); #endif // DELTA #if ENABLED(ULTIPANEL) @@ -1672,8 +1933,8 @@ void MarlinSettings::reset() { CONFIG_ECHO_START; SERIAL_ECHOLNPGM("Material heatup parameters:"); } - CONFIG_ECHO_START; for (uint8_t i = 0; i < COUNT(lcd_preheat_hotend_temp); i++) { + CONFIG_ECHO_START; SERIAL_ECHOPAIR(" M145 S", (int)i); SERIAL_ECHOPAIR(" H", TEMP_UNIT(lcd_preheat_hotend_temp[i])); SERIAL_ECHOPAIR(" B", TEMP_UNIT(lcd_preheat_bed_temp[i])); @@ -1769,7 +2030,7 @@ void MarlinSettings::reset() { #endif // FWRETRACT /** - * Auto Bed Leveling + * Probe Offset */ #if HAS_BED_PROBE if (!forReplay) { @@ -1780,6 +2041,24 @@ void MarlinSettings::reset() { SERIAL_ECHOLNPAIR(" M851 Z", LINEAR_UNIT(zprobe_zoffset)); #endif + /** + * Bed Skew Correction + */ + #if ENABLED(SKEW_CORRECTION_GCODE) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Skew Factor: "); + } + CONFIG_ECHO_START; + #if ENABLED(SKEW_CORRECTION_FOR_Z) + SERIAL_ECHOPAIR(" M852 I", LINEAR_UNIT(planner.xy_skew_factor)); + SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.xz_skew_factor)); + SERIAL_ECHOLNPAIR(" K", LINEAR_UNIT(planner.yz_skew_factor)); + #else + SERIAL_ECHOLNPAIR(" M852 S", LINEAR_UNIT(planner.xy_skew_factor)); + #endif + #endif + /** * TMC2130 stepper driver current */ @@ -1790,35 +2069,63 @@ void MarlinSettings::reset() { } CONFIG_ECHO_START; SERIAL_ECHO(" M906"); + #if ENABLED(X_IS_TMC2130) || ENABLED(X_IS_TMC2208) + SERIAL_ECHOPAIR(" X ", stepperX.getCurrent()); + #endif + #if ENABLED(Y_IS_TMC2130) || ENABLED(Y_IS_TMC2208) + SERIAL_ECHOPAIR(" Y ", stepperY.getCurrent()); + #endif + #if ENABLED(Z_IS_TMC2130) || ENABLED(Z_IS_TMC2208) + SERIAL_ECHOPAIR(" Z ", stepperZ.getCurrent()); + #endif + #if ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208) + SERIAL_ECHOPAIR(" X2 ", stepperX2.getCurrent()); + #endif + #if ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208) + SERIAL_ECHOPAIR(" Y2 ", stepperY2.getCurrent()); + #endif + #if ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208) + SERIAL_ECHOPAIR(" Z2 ", stepperZ2.getCurrent()); + #endif + #if ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208) + SERIAL_ECHOPAIR(" E0 ", stepperE0.getCurrent()); + #endif + #if ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208) + SERIAL_ECHOPAIR(" E1 ", stepperE1.getCurrent()); + #endif + #if ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208) + SERIAL_ECHOPAIR(" E2 ", stepperE2.getCurrent()); + #endif + #if ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208) + SERIAL_ECHOPAIR(" E3 ", stepperE3.getCurrent()); + #endif + #if ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208) + SERIAL_ECHOPAIR(" E4 ", stepperE4.getCurrent()); + #endif + SERIAL_EOL(); + #endif + + /** + * TMC2130 Sensorless homing thresholds + */ + #if ENABLED(HAVE_TMC2130) && ENABLED(SENSORLESS_HOMING) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Sensorless homing threshold:"); + } + CONFIG_ECHO_START; + SERIAL_ECHO(" M914"); #if ENABLED(X_IS_TMC2130) - SERIAL_ECHOPAIR(" X", stepperX.getCurrent()); - #endif - #if ENABLED(Y_IS_TMC2130) - SERIAL_ECHOPAIR(" Y", stepperY.getCurrent()); - #endif - #if ENABLED(Z_IS_TMC2130) - SERIAL_ECHOPAIR(" Z", stepperZ.getCurrent()); + SERIAL_ECHOPAIR(" X", stepperX.sgt()); #endif #if ENABLED(X2_IS_TMC2130) - SERIAL_ECHOPAIR(" X2", stepperX2.getCurrent()); + SERIAL_ECHOPAIR(" X2 ", stepperX2.sgt()); #endif - #if ENABLED(Y2_IS_TMC2130) - SERIAL_ECHOPAIR(" Y2", stepperY2.getCurrent()); + #if ENABLED(Y_IS_TMC2130) + SERIAL_ECHOPAIR(" Y", stepperY.sgt()); #endif - #if ENABLED(Z2_IS_TMC2130) - SERIAL_ECHOPAIR(" Z2", stepperZ2.getCurrent()); - #endif - #if ENABLED(E0_IS_TMC2130) - SERIAL_ECHOPAIR(" E0", stepperE0.getCurrent()); - #endif - #if ENABLED(E1_IS_TMC2130) - SERIAL_ECHOPAIR(" E1", stepperE1.getCurrent()); - #endif - #if ENABLED(E2_IS_TMC2130) - SERIAL_ECHOPAIR(" E2", stepperE2.getCurrent()); - #endif - #if ENABLED(E3_IS_TMC2130) - SERIAL_ECHOPAIR(" E3", stepperE3.getCurrent()); + #if ENABLED(X2_IS_TMC2130) + SERIAL_ECHOPAIR(" Y2 ", stepperY2.sgt()); #endif SERIAL_EOL(); #endif diff --git a/Marlin/configuration_store.h b/Marlin/configuration_store.h index 99e9511209..b20a8d4882 100644 --- a/Marlin/configuration_store.h +++ b/Marlin/configuration_store.h @@ -52,10 +52,10 @@ class MarlinSettings { #endif #if DISABLED(DISABLE_M503) - static void report(bool forReplay=false); + static void report(const bool forReplay=false); #else FORCE_INLINE - static void report(bool forReplay=false) { UNUSED(forReplay); } + static void report(const bool forReplay=false) { UNUSED(forReplay); } #endif private: diff --git a/Marlin/dogm_bitmaps.h b/Marlin/dogm_bitmaps.h index 9a77ff7853..4e0772a929 100644 --- a/Marlin/dogm_bitmaps.h +++ b/Marlin/dogm_bitmaps.h @@ -38,10 +38,8 @@ #if ENABLED(START_BMPHIGH) #define START_BMPWIDTH 112 #define START_BMPHEIGHT 38 - #define START_BMPBYTEWIDTH 14 - #define START_BMPBYTES 532 // START_BMPWIDTH * START_BMPHEIGHT / 8 - const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + const unsigned char start_bmp[] PROGMEM = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, @@ -83,10 +81,8 @@ #else #define START_BMPWIDTH 56 #define START_BMPHEIGHT 19 - #define START_BMPBYTEWIDTH 7 - #define START_BMPBYTES 133 // START_BMPWIDTH * START_BMPHEIGHT / 8 - const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + const unsigned char start_bmp[] PROGMEM = { 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, @@ -115,12 +111,55 @@ // When only one extruder is selected, the "1" on the symbol will not // be displayed. +#define STATUS_SCREENWIDTH 115 // Width in pixels +#define STATUS_SCREENHEIGHT 19 // Height in pixels + #if HAS_TEMP_BED - #if HOTENDS == 1 - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + #if HOTENDS == 0 + const unsigned char status_screen0_bmp[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + const unsigned char status_screen1_bmp[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 1 + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -142,10 +181,7 @@ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -167,10 +203,7 @@ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; #elif HOTENDS == 2 - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -192,10 +225,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -217,10 +247,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; #else - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -242,10 +269,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -266,13 +290,53 @@ 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 }; - #endif // Extruders + #endif // HOTENDS #else - #if HOTENDS == 1 - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + #if HOTENDS == 0 + const unsigned char status_screen0_bmp[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const unsigned char status_screen1_bmp[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 1 + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -294,10 +358,7 @@ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -319,10 +380,7 @@ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #elif HOTENDS == 2 - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -344,10 +402,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -369,10 +424,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #else - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen0_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, @@ -394,10 +446,7 @@ 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #define STATUS_SCREENWIDTH 115 //Width in pixels - #define STATUS_SCREENHEIGHT 19 //Height in pixels - #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes - const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + const unsigned char status_screen1_bmp[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, @@ -418,97 +467,97 @@ 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #endif // Extruders - - #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) - const unsigned char cw_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0x07,0xf8,0x00, // 000001111111100000000000 - 0x0c,0x0c,0x00, // 000011000000110000000000 - 0x10,0x02,0x00, // 000100000000001000000000 - 0x20,0x01,0x00, // 001000000000000100000000 - 0x60,0x01,0x80, // 011000000000000100000000 - 0x40,0x00,0x80, // 010000000000000010000000 - 0x40,0x03,0xe0, // 010000000000000011100000 - 0x40,0x01,0xc0, // 010000000000000011000000 - 0x40,0x00,0x80, // 010000000000000010000000 - 0x40,0x00,0x00, // 010000000000000000000000 - 0x40,0x00,0x00, // 010000000000000000000000 - 0x60,0x00,0x00, // 011000000000000000000000 - 0x20,0x00,0x00, // 001000000000000000000000 - 0x10,0x00,0x00, // 000100000000000000000000 - 0x0c,0x0c,0x00, // 000011000000110000000000 - 0x07,0xf8,0x00 // 000001111111100000000000 - }; - - const unsigned char ccw_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0x01,0xfe,0x00, // 000000011111111000000000 - 0x03,0x03,0x00, // 000000110000001100000000 - 0x04,0x00,0x80, // 000001000000000010000000 - 0x08,0x00,0x40, // 000010000000000001000000 - 0x18,0x00,0x60, // 000110000000000001100000 - 0x10,0x00,0x20, // 000100000000000000100000 - 0x7c,0x00,0x20, // 011111000000000000100000 - 0x38,0x00,0x20, // 001110000000000000100000 - 0x10,0x00,0x20, // 000100000000000000100000 - 0x00,0x00,0x20, // 000000000000000000100000 - 0x00,0x00,0x20, // 000000000000000000100000 - 0x00,0x00,0x60, // 000000000000000001100000 - 0x00,0x00,0x40, // 000000000000000001000000 - 0x00,0x00,0x80, // 000000000000000010000000 - 0x03,0x03,0x00, // 000000110000001100000000 - 0x01,0xfe,0x00 // 000000011111111000000000 - }; - - - const unsigned char up_arrow_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0x06,0x00, // 000001100000 - 0x0F,0x00, // 000011110000 - 0x1F,0x80, // 000111111000 - 0x3F,0xC0, // 001111111100 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00 // 000001100000 - }; - - const unsigned char down_arrow_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x06,0x00, // 000001100000 - 0x3F,0xC0, // 001111111100 - 0x1F,0x80, // 000111111000 - 0x0F,0x00, // 000011110000 - 0x06,0x00 // 000001100000 - }; - - const unsigned char offset_bedline_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0xFF,0xFF,0xFF // 111111111111111111111111 - }; - - const unsigned char nozzle_bmp[] PROGMEM = { //AVR-GCC, WinAVR - 0x7F,0x80, // 0111111110000000 - 0xFF,0xC0, // 1111111111000000 - 0xFF,0xC0, // 1111111111000000 - 0xFF,0xC0, // 1111111111000000 - 0x7F,0x80, // 0111111110000000 - 0x7F,0x80, // 0111111110000000 - 0xFF,0xC0, // 1111111111000000 - 0xFF,0xC0, // 1111111111000000 - 0xFF,0xC0, // 1111111111000000 - 0x3F,0x00, // 0011111100000000 - 0x1E,0x00, // 0001111000000000 - 0x0C,0x00 // 0000110000000000 - }; - #endif // BABYSTEP_ZPROBE_GFX_OVERLAY + #endif // HOTENDS #endif // HAS_TEMP_BED + +#if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) || ENABLED(MESH_EDIT_GFX_OVERLAY) + + const unsigned char cw_bmp[] PROGMEM = { + 0x03,0xF8,0x00, // 000000111111100000000000 + 0x0F,0xF7,0x00, // 000011111111111000000000 + 0x17,0x0F,0x00, // 000111100000111100000000 + 0x38,0x07,0x00, // 001110000000011100000000 + 0x38,0x03,0x80, // 001110000000001110000000 + 0x70,0x03,0x80, // 011100000000001110000000 + 0x70,0x0F,0xE0, // 011100000000111111100000 + 0x70,0x07,0xC0, // 011100000000011111000000 + 0x70,0x03,0x80, // 011100000000001110000000 + 0x70,0x01,0x00, // 011100000000000100000000 + 0x70,0x00,0x00, // 011100000000000000000000 + 0x68,0x00,0x00, // 001110000000000000000000 + 0x38,0x07,0x00, // 001110000000011100000000 + 0x17,0x0F,0x00, // 000111100000111100000000 + 0x0F,0xFE,0x00, // 000011111111111000000000 + 0x03,0xF8,0x00 // 000000111111100000000000 + }; + + const unsigned char ccw_bmp[] PROGMEM = { + 0x00,0xFE,0x00, // 000000001111111000000000 + 0x03,0xFF,0x80, // 000000111111111110000000 + 0x07,0x83,0xC0, // 000001111000001111000000 + 0x0E,0x01,0xC0, // 000011100000000111000000 + 0x0E,0x00,0xE0, // 000011100000000011100000 + 0x1C,0x00,0xE0, // 000111000000000011100000 + 0x7F,0x00,0xE0, // 011111110000000011100000 + 0x3E,0x00,0xE0, // 001111100000000011100000 + 0x1C,0x00,0xE0, // 000111000000000011100000 + 0x08,0x00,0xE0, // 000010000000000011100000 + 0x00,0x00,0xE0, // 000000000000000011100000 + 0x00,0x01,0xC0, // 000000000000000111000000 + 0x0E,0x01,0xC0, // 000011100000000111000000 + 0x0F,0x07,0x80, // 000011110000011110000000 + 0x07,0xFF,0x00, // 000001111111111100000000 + 0x01,0xFC,0x00 // 000000011111110000000000 + }; + + const unsigned char up_arrow_bmp[] PROGMEM = { + 0x04,0x00, // 000001000000 + 0x0E,0x00, // 000011100000 + 0x1F,0x00, // 000111110000 + 0x3F,0x80, // 001111111000 + 0x7F,0xC0, // 011111111100 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00 // 000011100000 + }; + + const unsigned char down_arrow_bmp[] PROGMEM = { + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x0E,0x00, // 000011100000 + 0x7F,0xC0, // 011111111100 + 0x3F,0x80, // 001111111000 + 0x1F,0x00, // 000111110000 + 0x0E,0x00, // 000011100000 + 0x04,0x00 // 000001000000 + }; + + const unsigned char offset_bedline_bmp[] PROGMEM = { + 0xFF,0xFF,0xFF // 111111111111111111111111 + }; + + const unsigned char nozzle_bmp[] PROGMEM = { + 0x7F,0x80, // 0111111110000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0x7F,0x80, // 0111111110000000 + 0x7F,0x80, // 0111111110000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0x3F,0x00, // 0011111100000000 + 0x1E,0x00, // 0001111000000000 + 0x0C,0x00 // 0000110000000000 + }; +#endif // BABYSTEP_ZPROBE_GFX_OVERLAY || MESH_EDIT_GFX_OVERLAY diff --git a/Marlin/dogm_font_data_ISO10646_1.h b/Marlin/dogm_font_data_ISO10646_1.h index 8ff40d054f..5e12ea86ff 100644 --- a/Marlin/dogm_font_data_ISO10646_1.h +++ b/Marlin/dogm_font_data_ISO10646_1.h @@ -32,167 +32,255 @@ Max Font ascent = 8 descent=-1 */ #include -const u8g_fntpgm_uint8_t ISO10646_1_5x7[2592] U8G_SECTION(".progmem.ISO10646_1_5x7") = { - 0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7, - 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, - 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, - 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, - 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, - 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, - 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, - 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, - 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, - 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, - 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, - 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, - 0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64, - 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, - 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, - 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, - 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, - 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, - 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, - 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, - 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, - 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, - 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, - 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, - 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, - 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, - 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, - 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, - 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, - 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, - 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, - 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, - 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, - 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, - 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, - 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, - 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, - 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, - 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, - 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, - 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, - 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, - 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, - 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, - 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, - 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, - 32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, - 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, - 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, - 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, - 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, - 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, - 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, - 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, - 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, - 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, - 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, - 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, - 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, - 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, - 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, - 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, - 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, - 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, - 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, - 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, - 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, - 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, - 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, - 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, - 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, - 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, - 6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, - 0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7, - 7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0, - 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112, - 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32, - 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8, - 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1, - 7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5, - 7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6, - 0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8, - 2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136, - 168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6, - 0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32, - 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5, - 5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64, - 128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, - 7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, - 2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6, - 0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136, - 136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, - 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, - 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, - 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, - 64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, - 136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136, - 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, - 8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, - 0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, - 32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, - 160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, - 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, - 248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, - 8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, - 6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, - 128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, - 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, - 64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, - 224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, - 8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, - 0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, - 16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, - 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, - 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, - 136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8, - 6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0, - 0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, - 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, - 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, - 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, - 32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224, - 4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8, - 8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, - 0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, - 32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, - 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, - 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, - 120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, - 6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, - 32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, - 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, - 248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, - 3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, - 8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, - 1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, - 160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, - 16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, - 136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, - 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, - 8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, - 0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, - 80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, - 0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5, - 8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, - 6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, - 0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, - 0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, - 136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96, - 64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112 -}; + +#if defined(__AVR__) && ENABLED(NOT_EXTENDED_ISO10646_1_5X7) + + // + // Reduced font (only symbols 32 - 127) - About 1400 bytes smaller + // + const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = { + 0,6,9,0,254,7,1,146,3,33,32,127,255,7,255,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168, + 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5, + 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6, + 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240, + 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240, + 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128, + 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7, + 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0, + 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16, + 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144, + 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7, + 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0, + 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136, + 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128, + 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5, + 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6, + 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248, + 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136, + 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32, + 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16, + 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128, + 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6, + 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32, + 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128, + 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6, + 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112, + 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136, + 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6, + 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112, + 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136, + 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3, + 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7, + 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0, + 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168, + 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5, + 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136, + 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8, + 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0, + 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64, + 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5, + 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136, + 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5, + 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0, + 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128, + 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128, + 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2, + 6,0,2,104,144,0,0,0,6,0,0}; + +#else + + // + // Extended (original) font (symbols 32 - 255) + // + const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, + 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, + 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, + 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, + 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, + 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, + 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, + 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, + 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, + 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, + 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, + 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, + 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, + 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, + 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, + 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, + 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, + 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, + 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, + 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, + 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, + 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, + 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, + 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, + 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, + 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, + 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, + 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, + 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, + 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, + 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, + 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, + 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, + 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, + 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, + 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, + 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, + 6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7, + 7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0, + 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112, + 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32, + 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8, + 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1, + 7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5, + 7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6, + 0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8, + 2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136, + 168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6, + 0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32, + 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5, + 5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64, + 128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, + 7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, + 2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6, + 0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136, + 136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, + 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, + 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, + 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, + 64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, + 136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136, + 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, + 0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, + 32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, + 160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, + 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, + 248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, + 8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, + 6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, + 128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, + 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, + 64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, + 224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, + 0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, + 16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, + 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, + 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, + 136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8, + 6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0, + 0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, + 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, + 32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224, + 4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8, + 8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, + 0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, + 32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, + 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, + 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, + 120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, + 6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, + 32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, + 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, + 248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, + 3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, + 8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, + 1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, + 160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, + 16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, + 136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, + 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, + 8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, + 0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, + 80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, + 0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5, + 8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, + 6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, + 0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, + 0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, + 136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96, + 64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112 + }; + +#endif diff --git a/Marlin/endstop_interrupts.h b/Marlin/endstop_interrupts.h index 7d37c77c66..6ad4fa55a4 100644 --- a/Marlin/endstop_interrupts.h +++ b/Marlin/endstop_interrupts.h @@ -111,7 +111,7 @@ void endstop_ISR(void) { endstop_ISR_worker(); } void setup_endstop_interrupts( void ) { #if HAS_X_MAX - #if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT) // if pin has an external interrupt + #if digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT // if pin has an external interrupt attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -121,7 +121,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_X_MIN - #if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -131,7 +131,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Y_MAX - #if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -141,7 +141,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Y_MIN - #if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -151,7 +151,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Z_MAX - #if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -161,7 +161,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Z_MIN - #if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -170,8 +170,48 @@ void setup_endstop_interrupts( void ) { #endif #endif + #if HAS_X2_MAX + #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X2_MAX_PIN) != NULL, "X2_MAX_PIN is not interrupt-capable"); + pciSetup(X2_MAX_PIN); + #endif + #endif + + #if HAS_X2_MIN + #if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X2_MIN_PIN) != NULL, "X2_MIN_PIN is not interrupt-capable"); + pciSetup(X2_MIN_PIN); + #endif + #endif + + #if HAS_Y2_MAX + #if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y2_MAX_PIN) != NULL, "Y2_MAX_PIN is not interrupt-capable"); + pciSetup(Y2_MAX_PIN); + #endif + #endif + + #if HAS_Y2_MIN + #if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y2_MIN_PIN) != NULL, "Y2_MIN_PIN is not interrupt-capable"); + pciSetup(Y2_MIN_PIN); + #endif + #endif + #if HAS_Z2_MAX - #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -181,7 +221,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Z2_MIN - #if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! @@ -191,7 +231,7 @@ void setup_endstop_interrupts( void ) { #endif #if HAS_Z_MIN_PROBE_PIN - #if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT) + #if digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE); #else // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! diff --git a/Marlin/endstops.cpp b/Marlin/endstops.cpp index 8ff6c7668a..1b1cab0230 100644 --- a/Marlin/endstops.cpp +++ b/Marlin/endstops.cpp @@ -41,7 +41,7 @@ Endstops endstops; bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load() volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value -#if ENABLED(Z_DUAL_ENDSTOPS) +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) uint16_t #else byte @@ -67,6 +67,14 @@ void Endstops::init() { #endif #endif + #if HAS_X2_MIN + #if ENABLED(ENDSTOPPULLUP_XMIN) + SET_INPUT_PULLUP(X2_MIN_PIN); + #else + SET_INPUT(X2_MIN_PIN); + #endif + #endif + #if HAS_Y_MIN #if ENABLED(ENDSTOPPULLUP_YMIN) SET_INPUT_PULLUP(Y_MIN_PIN); @@ -75,6 +83,14 @@ void Endstops::init() { #endif #endif + #if HAS_Y2_MIN + #if ENABLED(ENDSTOPPULLUP_YMIN) + SET_INPUT_PULLUP(Y2_MIN_PIN); + #else + SET_INPUT(Y2_MIN_PIN); + #endif + #endif + #if HAS_Z_MIN #if ENABLED(ENDSTOPPULLUP_ZMIN) SET_INPUT_PULLUP(Z_MIN_PIN); @@ -99,6 +115,14 @@ void Endstops::init() { #endif #endif + #if HAS_X2_MAX + #if ENABLED(ENDSTOPPULLUP_XMAX) + SET_INPUT_PULLUP(X2_MAX_PIN); + #else + SET_INPUT(X2_MAX_PIN); + #endif + #endif + #if HAS_Y_MAX #if ENABLED(ENDSTOPPULLUP_YMAX) SET_INPUT_PULLUP(Y_MAX_PIN); @@ -107,6 +131,14 @@ void Endstops::init() { #endif #endif + #if HAS_Y2_MAX + #if ENABLED(ENDSTOPPULLUP_YMAX) + SET_INPUT_PULLUP(Y2_MAX_PIN); + #else + SET_INPUT(Y2_MAX_PIN); + #endif + #endif + #if HAS_Z_MAX #if ENABLED(ENDSTOPPULLUP_ZMAX) SET_INPUT_PULLUP(Z_MAX_PIN); @@ -185,37 +217,45 @@ void Endstops::report_state() { void Endstops::M119() { SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT); + #define ES_REPORT(AXIS) do{ \ + SERIAL_PROTOCOLPGM(MSG_##AXIS); \ + SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \ + }while(0) #if HAS_X_MIN - SERIAL_PROTOCOLPGM(MSG_X_MIN); - SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(X_MIN); + #endif + #if HAS_X2_MIN + ES_REPORT(X2_MIN); #endif #if HAS_X_MAX - SERIAL_PROTOCOLPGM(MSG_X_MAX); - SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(X_MAX); + #endif + #if HAS_X2_MAX + ES_REPORT(X2_MAX); #endif #if HAS_Y_MIN - SERIAL_PROTOCOLPGM(MSG_Y_MIN); - SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Y_MIN); + #endif + #if HAS_Y2_MIN + ES_REPORT(Y2_MIN); #endif #if HAS_Y_MAX - SERIAL_PROTOCOLPGM(MSG_Y_MAX); - SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Y_MAX); + #endif + #if HAS_Y2_MAX + ES_REPORT(Y2_MAX); #endif #if HAS_Z_MIN - SERIAL_PROTOCOLPGM(MSG_Z_MIN); - SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z_MIN); #endif #if HAS_Z2_MIN - SERIAL_PROTOCOLPGM(MSG_Z2_MIN); - SERIAL_PROTOCOLLN(((READ(Z2_MIN_PIN)^Z2_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z2_MIN); #endif #if HAS_Z_MAX - SERIAL_PROTOCOLPGM(MSG_Z_MAX); - SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z_MAX); #endif #if HAS_Z2_MAX - SERIAL_PROTOCOLPGM(MSG_Z2_MAX); - SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z2_MAX); #endif #if ENABLED(Z_MIN_PROBE_ENDSTOP) SERIAL_PROTOCOLPGM(MSG_Z_PROBE); @@ -227,9 +267,27 @@ void Endstops::M119() { #endif } // Endstops::M119 +#if ENABLED(X_DUAL_ENDSTOPS) + void Endstops::test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2) { + byte x_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for X, bit 1 for X2 + if (x_test && stepper.current_block->steps[X_AXIS] > 0) { + SBI(endstop_hit_bits, X_MIN); + if (!stepper.performing_homing || (x_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + void Endstops::test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2) { + byte y_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Y, bit 1 for Y2 + if (y_test && stepper.current_block->steps[Y_AXIS] > 0) { + SBI(endstop_hit_bits, Y_MIN); + if (!stepper.performing_homing || (y_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - - // Pass the result of the endstop test void Endstops::test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2) { byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2 if (z_test && stepper.current_block->steps[Z_AXIS] > 0) { @@ -238,7 +296,6 @@ void Endstops::M119() { stepper.kill_current_block(); } } - #endif // Check endstops - Called from ISR! @@ -260,7 +317,7 @@ void Endstops::update() { _ENDSTOP_HIT(AXIS, MINMAX); \ stepper.endstop_triggered(_AXIS(AXIS)); \ } \ - } while(0) + }while(0) #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) // If G38 command is active check Z_MIN_PROBE for ALL movement @@ -357,18 +414,36 @@ void Endstops::update() { /** * Check and update endstops according to conditions */ - if (X_MOVE_TEST) { - if (stepper.motor_direction(X_AXIS_HEAD)) { - if (X_MIN_TEST) { // -direction - #if HAS_X_MIN - UPDATE_ENDSTOP(X, MIN); + if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction + #if HAS_X_MIN + #if ENABLED(X_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(X, MIN); + #if HAS_X2_MIN + UPDATE_ENDSTOP_BIT(X2, MIN); + #else + COPY_BIT(current_endstop_bits, X_MIN, X2_MIN); + #endif + test_dual_x_endstops(X_MIN, X2_MIN); + #else + if (X_MIN_TEST) UPDATE_ENDSTOP(X, MIN); #endif - } + #endif } - else if (X_MAX_TEST) { // +direction + else { // +direction #if HAS_X_MAX - UPDATE_ENDSTOP(X, MAX); + #if ENABLED(X_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(X, MAX); + #if HAS_X2_MAX + UPDATE_ENDSTOP_BIT(X2, MAX); + #else + COPY_BIT(current_endstop_bits, X_MAX, X2_MAX); + #endif + test_dual_x_endstops(X_MAX, X2_MAX); + #else + if (X_MIN_TEST) UPDATE_ENDSTOP(X, MAX); + #endif + #endif } } @@ -376,12 +451,32 @@ void Endstops::update() { if (Y_MOVE_TEST) { if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction #if HAS_Y_MIN - UPDATE_ENDSTOP(Y, MIN); + #if ENABLED(Y_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(Y, MIN); + #if HAS_Y2_MIN + UPDATE_ENDSTOP_BIT(Y2, MIN); + #else + COPY_BIT(current_endstop_bits, Y_MIN, Y2_MIN); + #endif + test_dual_y_endstops(Y_MIN, Y2_MIN); + #else + UPDATE_ENDSTOP(Y, MIN); + #endif #endif } else { // +direction #if HAS_Y_MAX - UPDATE_ENDSTOP(Y, MAX); + #if ENABLED(Y_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(Y, MAX); + #if HAS_Y2_MAX + UPDATE_ENDSTOP_BIT(Y2, MAX); + #else + COPY_BIT(current_endstop_bits, Y_MAX, Y2_MAX); + #endif + test_dual_y_endstops(Y_MAX, Y2_MAX); + #else + UPDATE_ENDSTOP(Y, MAX); + #endif #endif } } @@ -390,27 +485,21 @@ void Endstops::update() { if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. #if HAS_Z_MIN #if ENABLED(Z_DUAL_ENDSTOPS) - UPDATE_ENDSTOP_BIT(Z, MIN); #if HAS_Z2_MIN UPDATE_ENDSTOP_BIT(Z2, MIN); #else COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN); #endif - test_dual_z_endstops(Z_MIN, Z2_MIN); - - #else // !Z_DUAL_ENDSTOPS - + #else #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN); #else UPDATE_ENDSTOP(Z, MIN); #endif - - #endif // !Z_DUAL_ENDSTOPS - - #endif // HAS_Z_MIN + #endif + #endif // When closing the gap check the enabled probe #if ENABLED(Z_MIN_PROBE_ENDSTOP) @@ -422,27 +511,21 @@ void Endstops::update() { } else { // Z +direction. Gantry up, bed down. #if HAS_Z_MAX - // Check both Z dual endstops #if ENABLED(Z_DUAL_ENDSTOPS) - UPDATE_ENDSTOP_BIT(Z, MAX); #if HAS_Z2_MAX UPDATE_ENDSTOP_BIT(Z2, MAX); #else COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX); #endif - test_dual_z_endstops(Z_MAX, Z2_MAX); - // If this pin is not hijacked for the bed probe // then it belongs to the Z endstop #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN - UPDATE_ENDSTOP(Z, MAX); - - #endif // !Z_MIN_PROBE_PIN... - #endif // Z_MAX_PIN + #endif + #endif } } diff --git a/Marlin/endstops.h b/Marlin/endstops.h index 2788fb64ec..e60132d6e7 100644 --- a/Marlin/endstops.h +++ b/Marlin/endstops.h @@ -28,6 +28,7 @@ #define ENDSTOPS_H #include "enum.h" +#include "MarlinConfig.h" class Endstops { @@ -36,14 +37,22 @@ class Endstops { static bool enabled, enabled_globally; static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value - #if ENABLED(Z_DUAL_ENDSTOPS) + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) static uint16_t #else static byte #endif current_endstop_bits, old_endstop_bits; - Endstops() {}; + Endstops() { + enable_globally( + #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) + true + #else + false + #endif + ); + }; /** * Initialize the endstop pins @@ -85,6 +94,12 @@ class Endstops { private: + #if ENABLED(X_DUAL_ENDSTOPS) + static void test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + static void test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2); + #endif #if ENABLED(Z_DUAL_ENDSTOPS) static void test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2); #endif diff --git a/Marlin/enum.h b/Marlin/enum.h index c3e9ad0121..4fa6496c22 100644 --- a/Marlin/enum.h +++ b/Marlin/enum.h @@ -93,6 +93,10 @@ enum EndstopEnum { X_MAX, Y_MAX, Z_MAX, + X2_MIN, + X2_MAX, + Y2_MIN, + Y2_MAX, Z2_MIN, Z2_MAX }; diff --git a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration.h b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration.h index 12129c70e4..eb2af3f88b 100644 --- a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration.h +++ b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 70 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX 74 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 70 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX 74 // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 16 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // Buda 2.0 on 24V @@ -448,12 +451,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -593,7 +597,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -706,14 +710,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -805,10 +811,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 250 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -828,7 +854,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -854,12 +880,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -886,6 +907,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -941,7 +980,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -952,8 +993,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1013,14 +1054,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (8*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1052,7 +1150,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1197,11 +1295,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1329,8 +1427,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1438,11 +1536,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1550,7 +1650,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1608,17 +1714,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1634,11 +1740,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1653,22 +1759,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1681,40 +1787,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h index eec1b6c11f..695f1a43ce 100644 --- a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h +++ b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 4 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/AliExpress/CL-260/Configuration.h b/Marlin/example_configurations/AliExpress/CL-260/Configuration.h index f3bd3290fa..cb44364d4c 100644 --- a/Marlin/example_configurations/AliExpress/CL-260/Configuration.h +++ b/Marlin/example_configurations/AliExpress/CL-260/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 260 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1309,8 +1407,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Anet/A6/Configuration.h b/Marlin/example_configurations/Anet/A6/Configuration.h index a371f3e8be..aa7c676b7e 100644 --- a/Marlin/example_configurations/Anet/A6/Configuration.h +++ b/Marlin/example_configurations/Anet/A6/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -448,12 +451,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -630,7 +634,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -765,14 +769,16 @@ #define XY_PROBE_SPEED 8000 //#define XY_PROBE_SPEED 6000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 3) -// Use double touch for probing -#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -904,10 +910,30 @@ #define X_MAX_POS X_BED_SIZE #define Y_MAX_POS Y_BED_SIZE -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -927,7 +953,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -953,12 +979,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -985,6 +1006,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1064,7 +1103,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1075,8 +1116,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1141,16 +1182,16 @@ #define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). //Anet A6 with new X-Axis - //#define Z_SAFE_HOMING_X_POINT 113 // X point for Z homing when homing all axis (G28). - //#define Z_SAFE_HOMING_Y_POINT 112 // Y point for Z homing when homing all axis (G28). + //#define Z_SAFE_HOMING_X_POINT 113 // X point for Z homing when homing all axes (G28). + //#define Z_SAFE_HOMING_Y_POINT 112 // Y point for Z homing when homing all axes (G28). //Anet A6 with new X-Axis and defined X_HOME_POS -7, Y_HOME_POS -6 - //#define Z_SAFE_HOMING_X_POINT 107 // X point for Z homing when homing all axis (G28). - //#define Z_SAFE_HOMING_Y_POINT 107 // Y point for Z homing when homing all axis (G28). + //#define Z_SAFE_HOMING_X_POINT 107 // X point for Z homing when homing all axes (G28). + //#define Z_SAFE_HOMING_Y_POINT 107 // Y point for Z homing when homing all axes (G28). #endif @@ -1158,6 +1199,63 @@ #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1189,7 +1287,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1334,11 +1432,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1466,8 +1564,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1577,11 +1675,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + #define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1689,7 +1789,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1747,17 +1853,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1773,11 +1879,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1792,22 +1898,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1820,40 +1926,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Anet/A6/Configuration_adv.h b/Marlin/example_configurations/Anet/A6/Configuration_adv.h index b4e0f6a738..5fb2585bc8 100644 --- a/Marlin/example_configurations/Anet/A6/Configuration_adv.h +++ b/Marlin/example_configurations/Anet/A6/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 60 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 5 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 5 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 180 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). //#define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -601,15 +657,14 @@ */ //#define BABYSTEPPING #if ENABLED(BABYSTEPPING) - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Anet/A8/Configuration.h b/Marlin/example_configurations/Anet/A8/Configuration.h index 11ed3dfe08..4cba9c1565 100644 --- a/Marlin/example_configurations/Anet/A8/Configuration.h +++ b/Marlin/example_configurations/Anet/A8/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,10 @@ // :[1, 2, 3, 4, 5] #define EXTRUDERS 1 +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +// The Anet A8 original extruder is designed for 1.75mm +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +340,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +352,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 15 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -422,7 +426,7 @@ // or to allow moving the extruder regardless of the hotend temperature. // *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** #define PREVENT_COLD_EXTRUSION -#define EXTRUDE_MINTEMP 170 +#define EXTRUDE_MINTEMP 160 // 160 guards against false tripping when the extruder fan kicks on. // This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. // Note that for Bowden Extruders a too-small value here may prevent loading. @@ -434,12 +438,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -531,7 +536,7 @@ * Override with M92 * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 95 } +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 100 } /** * Default Max Feed Rate (mm/s) @@ -579,7 +584,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -692,14 +697,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 6000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -791,10 +798,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 240 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -814,7 +841,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -840,12 +867,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -872,6 +894,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -927,7 +967,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -938,8 +980,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -999,14 +1041,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (100*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1038,7 +1137,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1183,11 +1282,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1315,8 +1414,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1426,11 +1525,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1538,7 +1639,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1596,17 +1703,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1622,11 +1729,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1641,22 +1748,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1669,40 +1776,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Anet/A8/Configuration_adv.h b/Marlin/example_configurations/Anet/A8/Configuration_adv.h index 039e0b59b5..ef4215f48c 100644 --- a/Marlin/example_configurations/Anet/A8/Configuration_adv.h +++ b/Marlin/example_configurations/Anet/A8/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 60 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 5 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 180 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). //#define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/BQ/Hephestos/Configuration.h b/Marlin/example_configurations/BQ/Hephestos/Configuration.h index 592cfe15f7..989c5f4514 100644 --- a/Marlin/example_configurations/BQ/Hephestos/Configuration.h +++ b/Marlin/example_configurations/BQ/Hephestos/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -139,6 +139,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -339,8 +342,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -350,7 +354,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // Hephestos i3 #define DEFAULT_Kp 23.05 @@ -419,12 +422,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -564,7 +568,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -677,14 +681,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -776,10 +782,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 180 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -799,7 +825,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -825,12 +851,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -857,6 +878,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -912,7 +951,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -923,8 +964,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -984,14 +1025,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY 2000 #define HOMING_FEEDRATE_Z 150 +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1023,7 +1121,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1168,13 +1266,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1300,8 +1398,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1409,11 +1507,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1521,7 +1621,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1579,17 +1685,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1605,11 +1711,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1624,22 +1730,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1652,40 +1758,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h index af68c57007..0754ad82d6 100644 --- a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h +++ b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/BQ/Hephestos_2/Configuration.h b/Marlin/example_configurations/BQ/Hephestos_2/Configuration.h index f7fdd8e3d9..db3df34fdd 100644 --- a/Marlin/example_configurations/BQ/Hephestos_2/Configuration.h +++ b/Marlin/example_configurations/BQ/Hephestos_2/Configuration.h @@ -22,7 +22,7 @@ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //================================= README ================================== @@ -135,6 +135,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -341,8 +344,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -352,7 +356,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 50 // 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 K1 0.95 //smoothing factor within the PID // Tuned PID values using M303 #define DEFAULT_Kp 19.18 @@ -429,12 +432,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -574,7 +578,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -687,14 +691,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -786,10 +792,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 210 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -809,7 +835,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -835,12 +861,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -867,6 +888,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -922,7 +961,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -933,8 +974,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -994,14 +1035,71 @@ #define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (60*60) #define HOMING_FEEDRATE_Z 120 +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1033,7 +1131,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1178,11 +1276,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1310,8 +1408,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1419,11 +1517,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1531,7 +1631,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1589,17 +1695,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1615,11 +1721,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1634,22 +1740,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1662,40 +1768,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 2.00 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.60 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h index a89e69784e..b0d9c168b8 100644 --- a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h +++ b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X #define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ #define DIGIPOT_MOTOR_CURRENT { 150, 170, 180, 190, 180 } // Values 0-255 (bq ZUM Mega 3D (default): X = 150 [~1.17A]; Y = 170 [~1.33A]; Z = 180 [~1.41A]; E0 = 190 [~1.49A]) //#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M104 S0\nM84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 #define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 32 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 0.25 // (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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/BQ/WITBOX/Configuration.h b/Marlin/example_configurations/BQ/WITBOX/Configuration.h index 27853e0459..791aa3b90b 100644 --- a/Marlin/example_configurations/BQ/WITBOX/Configuration.h +++ b/Marlin/example_configurations/BQ/WITBOX/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -139,6 +139,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -339,8 +342,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -350,7 +354,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // Witbox #define DEFAULT_Kp 22.2 @@ -419,12 +422,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -564,7 +568,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -677,14 +681,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -776,10 +782,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -799,7 +825,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -825,12 +851,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -857,6 +878,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -912,7 +951,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -923,8 +964,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -984,14 +1025,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (120*60) #define HOMING_FEEDRATE_Z 432 +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1023,7 +1121,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1168,13 +1266,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1300,8 +1398,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1409,11 +1507,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1521,7 +1621,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1579,17 +1685,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1605,11 +1711,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1624,22 +1730,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1652,40 +1758,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h index af68c57007..0754ad82d6 100644 --- a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h +++ b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h index 306e8a3daf..bb86cc9665 100644 --- a/Marlin/example_configurations/Cartesio/Configuration.h +++ b/Marlin/example_configurations/Cartesio/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -137,6 +137,9 @@ // :[1, 2, 3, 4, 5] #define EXTRUDERS 3 +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -337,8 +340,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -348,7 +352,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -427,12 +430,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -572,7 +576,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -685,14 +689,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -784,10 +790,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 400 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -807,7 +833,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -833,12 +859,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -865,6 +886,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -920,7 +959,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -931,8 +972,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -992,14 +1033,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (10*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1031,7 +1129,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1176,11 +1274,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1417,11 +1515,13 @@ #define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1529,7 +1629,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1587,17 +1693,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1613,11 +1719,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1632,22 +1738,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1660,40 +1766,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Cartesio/Configuration_adv.h b/Marlin/example_configurations/Cartesio/Configuration_adv.h index 61aa19e13f..541d85f145 100644 --- a/Marlin/example_configurations/Cartesio/Configuration_adv.h +++ b/Marlin/example_configurations/Cartesio/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X #define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Creality/CR-10/Configuration.h b/Marlin/example_configurations/Creality/CR-10/Configuration.h index fbab8cf82f..3aecfb7169 100755 --- a/Marlin/example_configurations/Creality/CR-10/Configuration.h +++ b/Marlin/example_configurations/Creality/CR-10/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -438,12 +441,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -583,7 +587,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -696,14 +700,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -795,10 +801,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 400 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -818,7 +844,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -844,12 +870,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -876,6 +897,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -931,7 +970,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -942,8 +983,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1003,14 +1044,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1042,7 +1140,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1187,11 +1285,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1319,8 +1417,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1428,11 +1526,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1540,7 +1640,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1598,17 +1704,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1624,11 +1730,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1643,22 +1749,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1671,42 +1777,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. -#define DEFAULT_STDDEV_FILAMENT_DIA 0.05 // Typical estimate for cheap filament -//#define DEFAULT_STDDEV_FILAMENT_DIA 0.02 // Typical advertised for higher quality filament - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT (DEFAULT_NOMINAL_FILAMENT_DIA+4*DEFAULT_STDDEV_FILAMENT_DIA) // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT (DEFAULT_NOMINAL_FILAMENT_DIA-4*DEFAULT_STDDEV_FILAMENT_DIA) // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h index adfd6aa508..5c5b15c433 100755 --- a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h +++ b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 #define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #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 false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -601,15 +657,14 @@ */ #define BABYSTEPPING #if ENABLED(BABYSTEPPING) - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 10 // Babysteps are very small. Increase for faster motion. - //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 10 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,50 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +#define DEFAULT_STDDEV_FILAMENT_DIA 0.05 // Typical estimate for cheap filament +//#define DEFAULT_STDDEV_FILAMENT_DIA 0.02 // Typical advertised for higher quality filament + +#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 (DEFAULT_STDDEV_FILAMENT_DIA*4) // (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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1378,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1560,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h index e919e5d86b..e6adc7dcc1 100644 --- a/Marlin/example_configurations/Felix/Configuration.h +++ b/Marlin/example_configurations/Felix/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // Felix 2.0+ electronics with v4 Hotend #define DEFAULT_Kp 12 @@ -409,12 +412,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -555,7 +559,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -668,14 +672,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -767,10 +773,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 235 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -790,7 +816,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -816,12 +842,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -848,6 +869,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -903,7 +942,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -914,8 +955,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -975,14 +1016,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1014,7 +1112,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1159,13 +1257,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1291,8 +1389,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1400,11 +1498,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1512,7 +1612,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1570,17 +1676,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1596,11 +1702,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1615,22 +1721,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1643,40 +1749,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h index 03ae2b21d5..9ffd8961cb 100644 --- a/Marlin/example_configurations/Felix/Configuration_adv.h +++ b/Marlin/example_configurations/Felix/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 3 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h index ae090bdab7..c0a44a543b 100644 --- a/Marlin/example_configurations/Felix/DUAL/Configuration.h +++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #define EXTRUDERS 2 +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // Felix 2.0+ electronics with v4 Hotend #define DEFAULT_Kp 12 @@ -409,12 +412,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -555,7 +559,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -668,14 +672,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -767,10 +773,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 235 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -790,7 +816,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -816,12 +842,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -848,6 +869,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -903,7 +942,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -914,8 +955,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -975,14 +1016,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1014,7 +1112,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1159,13 +1257,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1291,8 +1389,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1400,11 +1498,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1512,7 +1612,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1570,17 +1676,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1596,11 +1702,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1615,22 +1721,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1643,40 +1749,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration.h b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h similarity index 89% rename from Marlin/example_configurations/Folger Tech/i3-2020/Configuration.h rename to Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h index fea2f2ebd5..2b35f136b4 100644 --- a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration.h +++ b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -433,12 +436,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -578,7 +582,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -690,14 +694,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 7500 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -788,10 +794,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 175 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds //#define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -811,7 +837,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -837,12 +863,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -869,6 +890,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -926,7 +965,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. #define GRID_MAX_POINTS_Y 10 @@ -937,8 +978,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 25 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -998,14 +1039,71 @@ #define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (40*60) #define HOMING_FEEDRATE_Z (55) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1037,7 +1135,7 @@ // // M100 Free Memory Watcher // -#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1182,11 +1280,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1314,8 +1412,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1423,11 +1521,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1535,7 +1635,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1593,17 +1699,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1619,11 +1725,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1638,22 +1744,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ #define NUM_SERVOS 2 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1666,40 +1772,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. #define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h similarity index 81% rename from Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h rename to Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h index ae7d57084d..ef47b338e0 100644 --- a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h +++ b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * If you get false positives for "Heating failed", increase WATCH_TEMP_PERIOD + * and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set + * below 2. */ #define WATCH_TEMP_PERIOD 40 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -601,15 +657,14 @@ */ #define BABYSTEPPING #if ENABLED(BABYSTEPPING) - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 2 // Babysteps are very small. Increase for faster motion. - //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 2 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Geeetech/GT2560/Configuration.h b/Marlin/example_configurations/Geeetech/GT2560/Configuration.h index da9cf6909c..49f2ca223b 100644 --- a/Marlin/example_configurations/Geeetech/GT2560/Configuration.h +++ b/Marlin/example_configurations/Geeetech/GT2560/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // Geeetech MK8 Extruder #define DEFAULT_Kp 12.33 @@ -443,12 +446,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -588,7 +592,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -701,14 +705,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -800,10 +806,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -823,7 +849,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -849,12 +875,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -881,6 +902,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -936,7 +975,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -947,8 +988,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1008,14 +1049,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1047,7 +1145,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1192,11 +1290,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1324,8 +1422,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1433,11 +1531,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1545,7 +1645,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1603,17 +1709,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1629,11 +1735,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1648,22 +1754,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1676,46 +1782,10 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - /** * Customize common displays for GT2560 */ -#if ENABLED(ULTIMAKERCONTROLLER) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) +#if ENABLED(ULTIMAKERCONTROLLER) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) || ENABLED(MKS_MINI_12864) #define SDSUPPORT // Force SD Card support on for these displays #elif ENABLED(ULTRA_LCD) && ENABLED(DOGLCD) // No panel, just graphical LCD? #define LCD_WIDTH 20 // Default is 22. For this Geeetech use 20 diff --git a/Marlin/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h b/Marlin/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h index 00bf9dc7e1..f10fc3b160 100644 --- a/Marlin/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h +++ b/Marlin/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 170 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ #define NUM_SERVOS 1 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Infitary/i3-M508/Configuration.h b/Marlin/example_configurations/Infitary/i3-M508/Configuration.h index 284b875d81..e5d17dc8b0 100644 --- a/Marlin/example_configurations/Infitary/i3-M508/Configuration.h +++ b/Marlin/example_configurations/Infitary/i3-M508/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -432,12 +435,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -577,7 +581,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -690,14 +694,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -789,10 +795,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 185 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -812,7 +838,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -838,12 +864,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -870,6 +891,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -925,7 +964,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -936,8 +977,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -997,14 +1038,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1036,7 +1134,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1181,11 +1279,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1313,8 +1411,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1422,11 +1520,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1534,7 +1634,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1592,17 +1698,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1618,11 +1724,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1637,22 +1743,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1665,40 +1771,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h index 811e6d625f..b739a09d0e 100644 --- a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h +++ b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 1 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ #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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ //#define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Malyan/M150/Configuration.h b/Marlin/example_configurations/Malyan/M150/Configuration.h index f9a5bb8b66..405b8b6f6e 100644 --- a/Marlin/example_configurations/Malyan/M150/Configuration.h +++ b/Marlin/example_configurations/Malyan/M150/Configuration.h @@ -42,7 +42,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -141,6 +141,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -344,8 +347,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -355,7 +359,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -436,12 +439,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -593,7 +597,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -710,14 +714,16 @@ // X and Y axis travel speed (mm/m) between probes //#define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) //#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point //#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -809,10 +815,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 180 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -832,7 +858,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -858,12 +884,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -894,6 +915,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -949,7 +988,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -960,8 +1001,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1021,14 +1062,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1060,7 +1158,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1205,11 +1303,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1337,8 +1435,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1446,11 +1544,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1558,7 +1658,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1616,17 +1722,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1642,11 +1748,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1661,22 +1767,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1689,40 +1795,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h index f16d9c2cc8..3082cb92c1 100644 --- a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h +++ b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 #define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Micromake/C1/README.md b/Marlin/example_configurations/Micromake/C1/README.md new file mode 100644 index 0000000000..0111f6f00a --- /dev/null +++ b/Marlin/example_configurations/Micromake/C1/README.md @@ -0,0 +1,15 @@ +# Micromake C1 + +### In the folder "basic" +Configuration files for Micromake C1 without mods + - English LCD 2X16 Characters + - Motors 16 STEPS + - No heated bed + - No probe, etc. + - Like a standard C1 as shipped by Micromake. + +### In the folder "enhanced" +Configuration files for Micromake C1 with… + - 128 STEPS configured with jumper on the motherboard (all open for 128 Steps). + - Capacitive Probe (Adjust offsets at your convenience) + - French language with no accents for Japanese LCD. diff --git a/Marlin/example_configurations/Micromake/C1/basic/Configuration.h b/Marlin/example_configurations/Micromake/C1/basic/Configuration.h new file mode 100644 index 0000000000..f66fbc578e --- /dev/null +++ b/Marlin/example_configurations/Micromake/C1/basic/Configuration.h @@ -0,0 +1,1774 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * 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 + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010107 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(MetalSearch, Micromake C1 factory settings)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MAKEBOARD_MINI +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Micromake C1" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#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 3.0 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // 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 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#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 + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_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 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for 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 +#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} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 3 : Mendel-parts thermistor (4.7k pullup) + * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! + * 5 : 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) + * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) + * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) + * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) + * 10 : 100k RS thermistor 198-961 (4.7k pullup) + * 11 : 100k beta 3950 1% thermistor (4.7k pullup) + * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) + * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup) + * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) + * + * 1047 : Pt1000 with 4k7 pullup + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * 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. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#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_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings +// from the two sensors differ too much the print will be aborted. +//#define TEMP_SENSOR_1_AS_REDUNDANT +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should 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 BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning + +// Comment the following line to disable PID and enable bang-bang. +#define PIDTEMP +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#define PID_DEBUG // Sends debug data to the serial port. + //#define PID_OPENLOOP 1 // 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_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) + // Set/get with gcode: M301 E[extruder number, 0-2] + #define PID_FUNCTIONAL_RANGE 10 // 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. + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Ultimaker + #define DEFAULT_Kp 22.2 + #define DEFAULT_Ki 1.08 + #define DEFAULT_Kd 114 + + // MakerGear + //#define DEFAULT_Kp 7.0 + //#define DEFAULT_Ki 0.1 + //#define DEFAULT_Kd 12 + + // Mendel Parts V9 on 12V + //#define DEFAULT_Kp 63.0 + //#define DEFAULT_Ki 2.25 + //#define DEFAULT_Kd 440 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you 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, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn'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 + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + #define DEFAULT_bedKp 10.00 + #define DEFAULT_bedKi .023 + #define DEFAULT_bedKd 305.4 + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from pidautotune + //#define DEFAULT_bedKp 97.1 + //#define DEFAULT_bedKi 1.41 + //#define DEFAULT_bedKd 1675.16 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// 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 + +//============================================================================= +//============================== 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 (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +// choose your micro step per step configuration ( 16 factory settings ) +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 150 } // 16 steps per unit for Micromake C1 - Factory Settings - ( MS1 : closed ; MS2 : closed on MAKEBOARD Mini) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 200, 200, 200, 300 } // 32 steps per unit for Micromake C1 - Custom Settings - ( MS1 : closed ; MS2 : open on MAKEBOARD Mini) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 400, 400, 400, 600 } // 64 steps per unit for Micromake C1 - Custom Settings - ( MS1 : open ; MS2 : closed on MAKEBOARD Mini) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 800, 800, 800, 1200 } // 128 steps per unit for Micromake C1 - Custom Settings - ( MS1 : open ; MS2 : open on MAKEBOARD Mini) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 30 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ + #define DEFAULT_MAX_ACCELERATION { 3000, 3000, 3000, 4000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (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 DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 20.0 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/docs/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * 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 + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#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 +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// 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. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 + +/** + * 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 Z_PROBE_OFFSET_FROM_EXTRUDER, 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 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// WARNING: When motors turn off there is a chance of losing position accuracy! +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z false +// Warn on display about possibly reduced accuracy +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @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 + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// 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 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 240 +#define Y_BED_SIZE 240 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 260 + +/** + * 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 curtail movement below 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 +#endif + +// Max software endstops curtail movement above 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 +#endif + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== 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 + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // 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 + + // + // Experimental 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_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#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 // Mesh inset margin on print area + #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_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #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 + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #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 + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + + +// @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 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - Allow Z homing only after X and Y homing AND stepper drivers still enabled. +// - If stepper drivers time out, it will need X and Y homing again before Z homing. +// - Move the Z probe (or nozzle) to a defined XY point before Z Homing when homing all axes (G28). +// - Prevent Z homing when the Z probe is outside bed area. +// +//#define Z_SAFE_HOMING + +#if ENABLED(Z_SAFE_HOMING) + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// 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 + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage + +// +// G20/G21 Inch mode support +// +#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * 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 } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * 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. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * 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 + +/** + * 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 + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#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 http://marlinfw.org/docs/development/lcd_language.html + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * 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: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// 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 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * 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 + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// 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 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET and Tronxy Controller supported displays. +// +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// 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 +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// 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 + +// +// 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 + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// 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. +#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 + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// SkeinForge sends the wrong arc g-codes when using Arc Point as fillet procedure +//#define SF_ARC_FIX + +// Support for the BariCUDA Paste Extruder +//#define BARICUDA + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * 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 MOFSET 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. + * *** CAUTION *** + * + * LED Type. Enable only one of the following two options. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(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 + +// Support for Adafruit Neopixel LED driver +//#define NEOPIXEL_LED +#if ENABLED(NEOPIXEL_LED) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 +#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 ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ + +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) 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 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +#endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Micromake/C1/enhanced/Configuration.h b/Marlin/example_configurations/Micromake/C1/enhanced/Configuration.h new file mode 100644 index 0000000000..7d94d844fa --- /dev/null +++ b/Marlin/example_configurations/Micromake/C1/enhanced/Configuration.h @@ -0,0 +1,1774 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * 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 + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010107 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(MetalSearch, Micromake C1 enhanced)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MAKEBOARD_MINI +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Micromake C1" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#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 3.0 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // 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 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#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 + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_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 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for 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 +#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} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 3 : Mendel-parts thermistor (4.7k pullup) + * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! + * 5 : 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) + * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) + * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) + * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) + * 10 : 100k RS thermistor 198-961 (4.7k pullup) + * 11 : 100k beta 3950 1% thermistor (4.7k pullup) + * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) + * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup) + * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) + * + * 1047 : Pt1000 with 4k7 pullup + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * 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. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#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_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings +// from the two sensors differ too much the print will be aborted. +//#define TEMP_SENSOR_1_AS_REDUNDANT +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should 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 BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning + +// Comment the following line to disable PID and enable bang-bang. +#define PIDTEMP +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#define PID_DEBUG // Sends debug data to the serial port. + //#define PID_OPENLOOP 1 // 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_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) + // Set/get with gcode: M301 E[extruder number, 0-2] + #define PID_FUNCTIONAL_RANGE 10 // 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. + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Ultimaker + #define DEFAULT_Kp 22.2 + #define DEFAULT_Ki 1.08 + #define DEFAULT_Kd 114 + + // MakerGear + //#define DEFAULT_Kp 7.0 + //#define DEFAULT_Ki 0.1 + //#define DEFAULT_Kd 12 + + // Mendel Parts V9 on 12V + //#define DEFAULT_Kp 63.0 + //#define DEFAULT_Ki 2.25 + //#define DEFAULT_Kd 440 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you 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, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn'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 + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + #define DEFAULT_bedKp 10.00 + #define DEFAULT_bedKi .023 + #define DEFAULT_bedKd 305.4 + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from pidautotune + //#define DEFAULT_bedKp 97.1 + //#define DEFAULT_bedKi 1.41 + //#define DEFAULT_bedKd 1675.16 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// 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 + +//============================================================================= +//============================== 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 (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +// choose your micro step per step configuration ( 16 factory settings ) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 150 } // 16 steps per unit for Micromake C1 - Factory Settings - ( MS1 : closed ; MS2 : closed on MAKEBOARD Mini) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 200, 200, 200, 300 } // 32 steps per unit for Micromake C1 - Custom Settings - ( MS1 : closed ; MS2 : open on MAKEBOARD Mini) +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 400, 400, 400, 600 } // 64 steps per unit for Micromake C1 - Custom Settings - ( MS1 : open ; MS2 : closed on MAKEBOARD Mini) +#define DEFAULT_AXIS_STEPS_PER_UNIT { 800, 800, 800, 1200 } // 128 steps per unit for Micromake C1 - Custom Settings - ( MS1 : open ; MS2 : open on MAKEBOARD Mini) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ + #define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 30 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ + #define DEFAULT_MAX_ACCELERATION { 3000, 3000, 3000, 4000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (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 DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/docs/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * 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 + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#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 +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// 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. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +#define MULTIPLE_PROBING 2 + +/** + * 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 Z_PROBE_OFFSET_FROM_EXTRUDER, 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 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// WARNING: When motors turn off there is a chance of losing position accuracy! +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z false +// Warn on display about possibly reduced accuracy +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @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 + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// 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 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 240 +#define Y_BED_SIZE 240 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 260 + +/** + * 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 curtail movement below 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 +#endif + +// Max software endstops curtail movement above 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 +#endif + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== 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 + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // 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 + + // + // Experimental 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_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#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 // Mesh inset margin on print area + #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_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #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 + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #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 + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + + +// @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 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - Allow Z homing only after X and Y homing AND stepper drivers still enabled. +// - If stepper drivers time out, it will need X and Y homing again before Z homing. +// - Move the Z probe (or nozzle) to a defined XY point before Z Homing when homing all axes (G28). +// - Prevent Z homing when the Z probe is outside bed area. +// +//#define Z_SAFE_HOMING + +#if ENABLED(Z_SAFE_HOMING) + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// 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 + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage + +// +// G20/G21 Inch mode support +// +#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * 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 } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * 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. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * 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 + +/** + * 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 + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE fr + +/** + * 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 http://marlinfw.org/docs/development/lcd_language.html + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * 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: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// 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 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * 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 + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// 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 100 +#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET and Tronxy Controller supported displays. +// +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// 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 +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// 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 + +// +// 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 + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// 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. +#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 + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// SkeinForge sends the wrong arc g-codes when using Arc Point as fillet procedure +//#define SF_ARC_FIX + +// Support for the BariCUDA Paste Extruder +//#define BARICUDA + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * 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 MOFSET 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. + * *** CAUTION *** + * + * LED Type. Enable only one of the following two options. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(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 + +// Support for Adafruit Neopixel LED driver +//#define NEOPIXEL_LED +#if ENABLED(NEOPIXEL_LED) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 +#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 ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ + +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) 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 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +#endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Micromake/C1/enhanced/Configuration_adv.h b/Marlin/example_configurations/Micromake/C1/enhanced/Configuration_adv.h new file mode 100644 index 0000000000..b7d436d7e8 --- /dev/null +++ b/Marlin/example_configurations/Micromake/C1/enhanced/Configuration_adv.h @@ -0,0 +1,1574 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * 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 + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010107 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control + #if ENABLED(BED_LIMIT_SWITCHING) + #define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS + #endif +#endif + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too + * long (period), the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * 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 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * As described above, except for the bed (M140/M190/M303). + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#endif + +/** + * Automatic Temperature: + * The hotend target temperature is calculated by all the buffered lines of gcode. + * The maximum buffered steps/sec of the extruder motor is called "se". + * Start autotemp mode with M109 S B F + * The target temperature is set to mintemp+factor*se[steps/sec] and is limited by + * mintemp and maxtemp. Turn this off by executing M109 without F* + * Also, if the temperature is set to a value below mintemp, it will not be changed by autotemp. + * On an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show extra position information in M114 +//#define M114_DETAIL + +// 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 HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_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 min_temp_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 MILLISECONDS_PREHEAT_TIME 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/m + #define EXTRUDER_RUNOUT_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * Controller Fan + * To cool down the stepper drivers and MOSFETs. + * + * The fan will turn on automatically whenever any stepper is enabled + * and turn off after a set period after all steppers are turned off. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // Set a custom pin for the controller fan + #define CONTROLLERFAN_SECS 60 // Duration in seconds for the fan to run after all motors are disabled + #define CONTROLLERFAN_SPEED 255 // 255 == full speed +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * 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 EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * 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 + +/** + * 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 MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// 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. + +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +//#define Z_DUAL_STEPPER_DRIVERS +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + //#define Z_DUAL_ENDSTOPS + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): 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) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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 hits each endstop, retracts by these distances, then does a slower bump. +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 2 +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#define INVERT_Z_STEP_PIN false +#define INVERT_E_STEP_PIN false + +// Default stepper release if idle. Set to 0 to deactivate. +// Steppers will shut down DEFAULT_STEPPER_DEACTIVE_TIME seconds after the last move when DISABLE_INACTIVE_? is true. +// Time can be set by M18 and M84. +#define DEFAULT_STEPPER_DEACTIVE_TIME 120 +#define DISABLE_INACTIVE_X true +#define DISABLE_INACTIVE_Y true +#define DISABLE_INACTIVE_Z true // set to false if the nozzle will fall down on your printed part when print has finished. +#define DISABLE_INACTIVE_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end +// of the buffer and all stops. This should not be much greater than zero and should only be changed +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {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, 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 + +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) +//#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + +#if ENABLED(SDSUPPORT) + + // Some RAMPS and other boards don't detect when an SD card is inserted. You can work + // around this by connecting a push button or single throw switch to the pin defined + // as SD_DETECT_PIN in your board's pins definitions. + // This setting should be disabled unless you are using a push button, pulling the pin to ground. + // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). + #define SD_DETECT_INVERTED + + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished + + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the 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 + + // Add an option in the menu to run all auto#.g files + //#define MENU_ADDAUTOSTART + + /** + * 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_LIMIT 40 // Maximum number of sorted items (10-256). Costs 27 bytes each. + #define FOLDER_SORTING -1 // -1=above 0=none 1=below + #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code. + #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. + #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) + #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + +#endif // SDSUPPORT + +/** + * 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 ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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 2300 bytes of PROGMEM. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + //#define USE_SMALL_INFOFONT + + // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#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 BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. + #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. + // Note: Extra time may be added to mitigate controller latency. + //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated segments between corrections + //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles + //#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Set MULTIPLE_PROBING if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// The number of linear motions that can be in the plan at any give time. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. +#if ENABLED(SDSUPPORT) + #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// 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 ENABLED(SDSUPPORT) + // 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 + +// Enable an emergency-command parser to intercept certain commands as they +// enter the serial receive buffer, so they cannot be blocked. +// Currently handles M108, M112, M410 +// Does not work on boards using AT90USB (USBCON) processors! +//#define EMERGENCY_PARSER + +// 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 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * 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 // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * 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 + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130, TMC2208 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 800 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 800 + #define Z_MICROSTEPS 16 + + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 + + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 + + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 + + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 + + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 + + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 + + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 + + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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 S0/1 - 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 + + /** + * 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 needs to be enabled. + * 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 E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * X and Y homing will always be done in spreadCycle mode. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING // TMC2130 only + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 + #endif + + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper + * + * Example: + * #define TMC_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperY.interpolate(0); \ + * } + */ + #define TMC_ADV() { } + +#endif // TMC2130 || TMC2208 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you 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 + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * 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 http://marlinfw.org/docs/configuration/laser_spindle.html for more config details. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #define SPINDLE_LASER_PWM true // set to true if your controller supports setting the speed/power + #define SPINDLE_LASER_PWM_INVERT true // set to "true" if the speed/power goes up when you want it to go slower + #define SPINDLE_LASER_POWERUP_DELAY 5000 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #define SPEED_POWER_SLOPE 118.4 + #define SPEED_POWER_INTERCEPT 0 + #define SPEED_POWER_MIN 5000 + #define SPEED_POWER_MAX 30000 // SuperPID router controller 0 - 30,000 RPM + + //#define SPEED_POWER_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * 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 + +/** + * 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 + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * 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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://wiki.aus3d.com.au/Magnetic_Encoder + * Github: https://github.com/Aus3D/MagneticEncoder + * + * Supplier: http://aus3d.com.au/magnetic-encoder-module + * Alternative Supplier: http://reliabuild3d.com/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#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_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #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 behaviour. + + #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 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * 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_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper 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. +#endif + +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h index 6b385741dc..c6eab8fa3b 100644 --- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h +++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1309,8 +1407,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h index 705b6679e0..f064688254 100644 --- a/Marlin/example_configurations/RigidBot/Configuration.h +++ b/Marlin/example_configurations/RigidBot/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -139,6 +139,9 @@ // :[1, 2, 3, 4, 5] #define EXTRUDERS 1 // Single extruder. Set to 2 for dual extruders +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -339,8 +342,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -350,7 +354,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -424,12 +427,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -571,7 +575,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -684,14 +688,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -783,10 +789,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 254 // RigidBot regular and Big are 254mm -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -806,7 +832,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -832,12 +858,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -864,6 +885,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -919,7 +958,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -930,8 +971,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -991,14 +1032,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (15*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1030,7 +1128,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1175,11 +1273,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1307,8 +1405,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/RigidBot/Configuration_adv.h b/Marlin/example_configurations/RigidBot/Configuration_adv.h index e488c51415..3f0fd39fd3 100644 --- a/Marlin/example_configurations/RigidBot/Configuration_adv.h +++ b/Marlin/example_configurations/RigidBot/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h index a927723d33..3fd3b32bb9 100644 --- a/Marlin/example_configurations/SCARA/Configuration.h +++ b/Marlin/example_configurations/SCARA/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -166,6 +166,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -366,8 +369,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -377,7 +381,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #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 K1 0.95 //smoothing factor within the PID // Merlin Hotend: From Autotune #define DEFAULT_Kp 24.5 @@ -440,12 +443,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -585,7 +589,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -698,14 +702,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -797,10 +803,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 225 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -820,7 +846,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -846,12 +872,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -878,6 +899,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -933,7 +972,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -944,8 +985,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1005,14 +1046,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (40*60) #define HOMING_FEEDRATE_Z (10*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1044,7 +1142,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1189,13 +1287,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1321,8 +1419,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1430,11 +1528,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1542,7 +1642,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1600,17 +1706,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1626,11 +1732,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1645,22 +1751,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1673,40 +1779,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h index 0a92aeeb0d..1479efe32a 100644 --- a/Marlin/example_configurations/SCARA/Configuration_adv.h +++ b/Marlin/example_configurations/SCARA/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 3 #define Y_HOME_BUMP_MM 3 #define Z_HOME_BUMP_MM 3 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Sanguinololu/Configuration.h b/Marlin/example_configurations/Sanguinololu/Configuration.h index c65c5c3f6e..1df349815f 100644 --- a/Marlin/example_configurations/Sanguinololu/Configuration.h +++ b/Marlin/example_configurations/Sanguinololu/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -604,7 +608,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -717,14 +721,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -816,10 +822,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 170 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -839,7 +865,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -865,12 +891,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -897,6 +918,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -952,7 +991,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -963,8 +1004,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1024,14 +1065,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (6*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1063,7 +1161,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1212,7 +1310,7 @@ * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, tr, uk, * zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1340,8 +1438,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1449,11 +1547,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1561,7 +1661,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1619,17 +1725,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ #define RGB_LED @@ -1645,11 +1751,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1664,22 +1770,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1692,40 +1798,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h index 00401a88e6..34c8b4f13a 100644 --- a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h +++ b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -246,48 +248,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -334,12 +337,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -423,8 +426,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -455,6 +471,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -464,12 +497,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -506,6 +541,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -524,14 +561,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -564,6 +616,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -592,13 +648,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -645,23 +700,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -681,7 +731,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -706,7 +756,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -774,6 +824,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -884,7 +943,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -898,7 +957,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -913,46 +984,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -961,24 +1044,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -993,8 +1074,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1004,7 +1085,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1013,27 +1094,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1197,6 +1285,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1213,13 +1342,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1388,4 +1524,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/TinyBoy2/Configuration.h b/Marlin/example_configurations/TinyBoy2/Configuration.h index 2bfc23e5e4..9873fd7922 100644 --- a/Marlin/example_configurations/TinyBoy2/Configuration.h +++ b/Marlin/example_configurations/TinyBoy2/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 /** * Sample configuration file for TinyBoy2 L10/L16 @@ -158,6 +158,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -363,8 +366,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -374,7 +378,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -478,12 +481,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -624,7 +628,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -737,14 +741,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -841,10 +847,30 @@ #define Z_MAX_POS 158 #endif -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -864,7 +890,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -890,12 +916,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -922,6 +943,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -977,7 +1016,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -988,8 +1029,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1049,14 +1090,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (40*60) #define HOMING_FEEDRATE_Z (3*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1088,7 +1186,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1233,11 +1331,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1365,8 +1463,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1474,11 +1572,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1586,7 +1686,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1644,17 +1750,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1670,11 +1776,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1689,22 +1795,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1717,40 +1823,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h index 197f909d29..df6471d7a7 100644 --- a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h +++ b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Velleman/K8200/Configuration.h b/Marlin/example_configurations/Velleman/K8200/Configuration.h index acd732e040..c4db7ae333 100644 --- a/Marlin/example_configurations/Velleman/K8200/Configuration.h +++ b/Marlin/example_configurations/Velleman/K8200/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 /** * Sample configuration file for Vellemann K8200 @@ -156,6 +156,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -356,8 +359,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -367,7 +371,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -458,12 +461,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -602,7 +606,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -715,14 +719,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -815,10 +821,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -838,7 +864,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -864,12 +890,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -896,6 +917,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -951,7 +990,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -962,8 +1003,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1023,14 +1064,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1062,7 +1160,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1210,11 +1308,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1342,8 +1440,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1451,11 +1549,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1563,7 +1663,8 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller #endif // K8200_VM8201 @@ -1623,17 +1724,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1649,11 +1750,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1668,22 +1769,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1696,40 +1797,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h index 2e5fa1e708..63e2ed3f88 100644 --- a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h +++ b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h @@ -41,7 +41,7 @@ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -57,18 +57,20 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) // K8200 has weak heaters/power supply by default, so you have to relax! @@ -76,13 +78,16 @@ #define THERMAL_PROTECTION_HYSTERESIS 8 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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. */ // K8200 has weak heaters/power supply by default, so you have to relax! #define WATCH_TEMP_PERIOD 30 // Seconds @@ -99,13 +104,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 10 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -136,6 +135,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -270,48 +272,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -358,12 +361,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {4, 4, 8} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 4, 4, 8 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -447,8 +450,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -479,6 +495,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -488,7 +521,7 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. @@ -530,6 +563,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -548,14 +583,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 #define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -588,6 +638,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -616,13 +670,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -669,23 +722,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -705,7 +753,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -730,7 +778,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -820,6 +868,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -930,7 +987,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -944,7 +1001,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -959,46 +1028,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -1007,24 +1088,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1039,8 +1118,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1050,7 +1129,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1059,27 +1138,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1243,6 +1329,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1259,13 +1386,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1434,4 +1568,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Velleman/K8400/Configuration.h b/Marlin/example_configurations/Velleman/K8400/Configuration.h index 27ac63fe65..c3bba3aa8c 100644 --- a/Marlin/example_configurations/Velleman/K8400/Configuration.h +++ b/Marlin/example_configurations/Velleman/K8400/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 190 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (8*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1309,8 +1407,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h index b3cfc51b12..bd476f7195 100644 --- a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h +++ b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 10 #define Y_HOME_BUMP_MM 10 #define Z_HOME_BUMP_MM 3 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/Velleman/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/Velleman/K8400/Dual-head/Configuration.h index 0bcc957436..eec93ae6f1 100644 --- a/Marlin/example_configurations/Velleman/K8400/Dual-head/Configuration.h +++ b/Marlin/example_configurations/Velleman/K8400/Dual-head/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #define EXTRUDERS 2 +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 190 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (8*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1309,8 +1407,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration.h b/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration.h new file mode 100644 index 0000000000..e009f5d1b2 --- /dev/null +++ b/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration.h @@ -0,0 +1,1726 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * 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 + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010107 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Rob Mendon, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_ULTIMAIN_2 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Duplicator 6" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#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 + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // 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 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#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 + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_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 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for 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 +#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} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 3 : Mendel-parts thermistor (4.7k pullup) + * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! + * 5 : 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) + * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) + * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) + * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) + * 10 : 100k RS thermistor 198-961 (4.7k pullup) + * 11 : 100k beta 3950 1% thermistor (4.7k pullup) + * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) + * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup) + * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) + * + * 1047 : Pt1000 with 4k7 pullup + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * 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. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 20 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings +// from the two sensors differ too much the print will be aborted. +//#define TEMP_SENSOR_1_AS_REDUNDANT +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 260 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 120 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning + +// Comment the following line to disable PID and enable bang-bang. +#define PIDTEMP +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID +#if ENABLED(PIDTEMP) + #define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#define PID_DEBUG // Sends debug data to the serial port. + //#define PID_OPENLOOP 1 // 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_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) + // Set/get with gcode: M301 E[extruder number, 0-2] + #define PID_FUNCTIONAL_RANGE 10 // 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. + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Ultimaker + //#define DEFAULT_Kp 22.2 + //#define DEFAULT_Ki 1.08 + //#define DEFAULT_Kd 114 + + // MakerGear + //#define DEFAULT_Kp 7.0 + //#define DEFAULT_Ki 0.1 + //#define DEFAULT_Kd 12 + + // Mendel Parts V9 on 12V + //#define DEFAULT_Kp 63.0 + //#define DEFAULT_Ki 2.25 + //#define DEFAULT_Kd 440 + + // Duplicator 6 + #define DEFAULT_Kp 9.12 + #define DEFAULT_Ki 0.41 + #define DEFAULT_Kd 50.98 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you 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, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn'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 + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) +// #define DEFAULT_bedKp 10.00 +// #define DEFAULT_bedKi .023 +// #define DEFAULT_bedKd 305.4 + + //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + //from pidautotune + //#define DEFAULT_bedKp 97.1 + //#define DEFAULT_bedKi 1.41 + //#define DEFAULT_bedKd 1675.16 + + // Duplicator 6 + #define DEFAULT_bedKp 124.55 + #define DEFAULT_bedKi 23.46 + #define DEFAULT_bedKd 165.29 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// 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 + +//============================================================================= +//============================== 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 (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80.0395, 80.0395, 400.48, 99.1 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 500 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1500 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (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 DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 1.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/docs/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * 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 + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#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 +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// 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. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 + +/** + * 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 Z_PROBE_OFFSET_FROM_EXTRUDER, 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 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// WARNING: When motors turn off there is a chance of losing position accuracy! +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z false +// Warn on display about possibly reduced accuracy +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// 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 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 170 + +/** + * 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 curtail movement below 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 +#endif + +// Max software endstops curtail movement above 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 +#endif + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * 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 + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // 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 + + // + // Experimental 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_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#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 // Mesh inset margin on print area + #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_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #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 + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #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 + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + + +// @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 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - Allow Z homing only after X and Y homing AND stepper drivers still enabled. +// - If stepper drivers time out, it will need X and Y homing again before Z homing. +// - Move the Z probe (or nozzle) to a defined XY point before Z Homing when homing all axes (G28). +// - Prevent Z homing when the Z probe is outside bed area. +// +//#define Z_SAFE_HOMING + +#if ENABLED(Z_SAFE_HOMING) + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// 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 + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * 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 } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * 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. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * 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 + +/** + * 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 + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#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 http://marlinfw.org/docs/development/lcd_language.html + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * 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: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// 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 2 + +// +// 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 + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// 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 5 +#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET and Tronxy Controller supported displays. +// +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// 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 +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// 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 + +// +// SSD1306 OLED full graphics generic display +// +#define U8GLIB_SSD1306 +#define LCD_WIDTH 22 +#define LCD_HEIGHT 5 +#define LCD_RESET_PIN 5 + +// +// 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 + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// 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. +#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 + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// SkeinForge sends the wrong arc g-codes when using Arc Point as fillet procedure +//#define SF_ARC_FIX + +// Support for the BariCUDA Paste Extruder +//#define BARICUDA + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +#define PCA9632 + +/** + * 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 MOFSET 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. + * *** CAUTION *** + * + * LED Type. Enable only one of the following two options. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(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 + +// Support for Adafruit Neopixel LED driver +//#define NEOPIXEL_LED +#if ENABLED(NEOPIXEL_LED) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 +#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 ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ + +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) 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 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +#endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration_adv.h b/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration_adv.h new file mode 100644 index 0000000000..60ed13e252 --- /dev/null +++ b/Marlin/example_configurations/Wanhao/Duplicator 6/Configuration_adv.h @@ -0,0 +1,1575 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * 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 + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010107 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control + #if ENABLED(BED_LIMIT_SWITCHING) + #define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS + #endif +#endif + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too + * long (period), the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104, M109, or M303 increases the target temperature, the + * firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature + * hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and + * requires a hard reset. This test restarts with any M104/M109/M303, but only + * if the current temperature is far enough below the target for a reliable + * test. + * + * If you get false positives for "Heating failed", increase WATCH_TEMP_PERIOD + * and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set + * below 2. + */ + #define WATCH_TEMP_PERIOD 40 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 40 // Seconds Changed to 90 seconds to help prevent false thermal runaway errors (may have to increase to 120) + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * As described above, except for the bed (M140/M190/M303). + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds Changed to 90 seconds to help prevent false heater failed errors + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#endif + +/** + * Automatic Temperature: + * The hotend target temperature is calculated by all the buffered lines of gcode. + * The maximum buffered steps/sec of the extruder motor is called "se". + * Start autotemp mode with M109 S B F + * The target temperature is set to mintemp+factor*se[steps/sec] and is limited by + * mintemp and maxtemp. Turn this off by executing M109 without F* + * Also, if the temperature is set to a value below mintemp, it will not be changed by autotemp. + * On an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show extra position information in M114 +//#define M114_DETAIL + +// 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 HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_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 min_temp_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 MILLISECONDS_PREHEAT_TIME 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/m + #define EXTRUDER_RUNOUT_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * Controller Fan + * To cool down the stepper drivers and MOSFETs. + * + * The fan will turn on automatically whenever any stepper is enabled + * and turn off after a set period after all steppers are turned off. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // Set a custom pin for the controller fan + #define CONTROLLERFAN_SECS 60 // Duration in seconds for the fan to run after all motors are disabled + #define CONTROLLERFAN_SPEED 255 // 255 == full speed +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * 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 EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * 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 + +/** + * M355 Case Light on-off / brightness + */ +#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + #define CASE_LIGHT_PIN 8 // 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 255 // Set default power-up brightness (0-255, requires PWM pin) + #define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// 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. + +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +//#define Z_DUAL_STEPPER_DRIVERS +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + //#define Z_DUAL_ENDSTOPS + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif +#endif + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): 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) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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 hits each endstop, retracts by these distances, then does a slower bump. +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 2 +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#define INVERT_Z_STEP_PIN false +#define INVERT_E_STEP_PIN false + +// Default stepper release if idle. Set to 0 to deactivate. +// Steppers will shut down DEFAULT_STEPPER_DEACTIVE_TIME seconds after the last move when DISABLE_INACTIVE_? is true. +// Time can be set by M18 and M84. +#define DEFAULT_STEPPER_DEACTIVE_TIME 120 +#define DISABLE_INACTIVE_X true +#define DISABLE_INACTIVE_Y true +#define DISABLE_INACTIVE_Z true // set to false if the nozzle will fall down on your printed part when print has finished. +#define DISABLE_INACTIVE_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {70*60, 70*60, 15*60, 6*60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end +// of the buffer and all stops. This should not be much greater than zero and should only be changed +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {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, 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 + */ +//Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range +#define MOTOR_CURRENT_PWM_RANGE 2782 +#define PWM_MOTOR_CURRENT { 1200, 1200, 1000 } // 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 + +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) +//#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +#define LCD_TIMEOUT_TO_STATUS 60000 + +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + +#if ENABLED(SDSUPPORT) + + // Some RAMPS and other boards don't detect when an SD card is inserted. You can work + // around this by connecting a push button or single throw switch to the pin defined + // as SD_DETECT_PIN in your board's pins definitions. + // This setting should be disabled unless you are using a push button, pulling the pin to ground. + // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). + #define SD_DETECT_INVERTED + + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the 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 + + // Add an option in the menu to run all auto#.g files + //#define MENU_ADDAUTOSTART + + /** + * 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_LIMIT 40 // Maximum number of sorted items (10-256). Costs 27 bytes each. + #define FOLDER_SORTING -1 // -1=above 0=none 1=below + #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code. + #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. + #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) + #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + +#endif // SDSUPPORT + +/** + * 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 ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + //#define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + //#define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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 2300 bytes of PROGMEM. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + #define USE_SMALL_INFOFONT + + // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#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 BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. + #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. + // Note: Extra time may be added to mitigate controller latency. + //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 0 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated segments between corrections + //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles + //#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Set MULTIPLE_PROBING if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// The number of linear motions that can be in the plan at any give time. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. +#if ENABLED(SDSUPPORT) + #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// 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 ENABLED(SDSUPPORT) + // 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 + +// Enable an emergency-command parser to intercept certain commands as they +// enter the serial receive buffer, so they cannot be blocked. +// Currently handles M108, M112, M410 +// Does not work on boards using AT90USB (USBCON) processors! +//#define EMERGENCY_PARSER + +// 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 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * 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 // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * 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 + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130, TMC2208 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 800 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 800 + #define Z_MICROSTEPS 16 + + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 + + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 + + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 + + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 + + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 + + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 + + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 + + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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 S0/1 - 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 + + /** + * 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 needs to be enabled. + * 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 E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * X and Y homing will always be done in spreadCycle mode. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING // TMC2130 only + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 + #endif + + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper + * + * Example: + * #define TMC_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperY.interpolate(0); \ + * } + */ + #define TMC_ADV() { } + +#endif // TMC2130 || TMC2208 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you 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 + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * 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 http://marlinfw.org/docs/configuration/laser_spindle.html for more config details. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #define SPINDLE_LASER_PWM true // set to true if your controller supports setting the speed/power + #define SPINDLE_LASER_PWM_INVERT true // set to "true" if the speed/power goes up when you want it to go slower + #define SPINDLE_LASER_POWERUP_DELAY 5000 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #define SPEED_POWER_SLOPE 118.4 + #define SPEED_POWER_INTERCEPT 0 + #define SPEED_POWER_MIN 5000 + #define SPEED_POWER_MAX 30000 // SuperPID router controller 0 - 30,000 RPM + + //#define SPEED_POWER_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * 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 + +/** + * 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 + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * 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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://wiki.aus3d.com.au/Magnetic_Encoder + * Github: https://github.com/Aus3D/MagneticEncoder + * + * Supplier: http://aus3d.com.au/magnetic-encoder-module + * Alternative Supplier: http://reliabuild3d.com/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#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_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #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 behaviour. + + #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 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * 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_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper 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. +#endif + +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h index 09354c0e35..0de908a16b 100644 --- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h +++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -573,7 +577,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -686,14 +690,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -785,10 +791,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 200 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -808,7 +834,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -834,12 +860,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -866,6 +887,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -921,7 +960,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -932,8 +973,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -993,14 +1034,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1032,7 +1130,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1177,11 +1275,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1309,8 +1407,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1418,11 +1516,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1530,7 +1630,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1588,17 +1694,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1614,11 +1720,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1633,22 +1739,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1661,40 +1767,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h index f79ce2b3a0..53263cb696 100644 --- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h +++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) #define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -438,12 +441,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -486,7 +490,7 @@ // Delta calibration menu // uncomment to add three points calibration menu option. // See http://minow.blogspot.com/index.html#4918805519571907051 - #define DELTA_CALIBRATION_MENU + //#define DELTA_CALIBRATION_MENU // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) #define DELTA_AUTO_CALIBRATION @@ -496,10 +500,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 73.5 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -647,7 +657,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -760,14 +770,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 5000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST) / 6 -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -909,10 +921,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds //#define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -932,7 +964,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -958,12 +990,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -990,6 +1017,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1047,7 +1092,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1060,8 +1107,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1121,13 +1168,70 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (100*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1159,7 +1263,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1304,11 +1408,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1437,8 +1541,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1546,11 +1650,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1658,7 +1764,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1716,17 +1828,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1742,11 +1854,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1761,22 +1873,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1789,40 +1901,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 1.95 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.20 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h index 3286006763..a165ea79e3 100644 --- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h +++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 10, 10, 10 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -436,8 +439,21 @@ #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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -468,6 +484,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -477,12 +510,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -519,6 +554,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -537,14 +574,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -577,6 +629,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,15 +659,14 @@ */ //#define BABYSTEPPING #if ENABLED(BABYSTEPPING) - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. - //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -658,23 +713,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -694,7 +744,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -719,7 +769,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -809,6 +859,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -919,7 +978,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -933,7 +992,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -948,46 +1019,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -996,24 +1079,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1028,8 +1109,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1039,7 +1120,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1048,27 +1129,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1232,6 +1320,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1248,13 +1377,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1423,4 +1559,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h index 72e36a46ac..cc3adb22f7 100644 --- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h +++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) #define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -438,12 +441,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -496,10 +500,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 73.5 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -647,7 +657,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -760,14 +770,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 2000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -909,10 +921,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -932,7 +964,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -958,12 +990,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -990,6 +1017,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1041,7 +1086,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1054,8 +1101,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1115,13 +1162,70 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_MIN_POS + X_MAX_POS) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_MIN_POS + Y_MAX_POS) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_MIN_POS + X_MAX_POS) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_MIN_POS + Y_MAX_POS) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (45*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1153,7 +1257,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1298,11 +1402,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1430,8 +1534,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1539,11 +1643,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1651,7 +1757,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1709,17 +1821,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1735,11 +1847,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1754,22 +1866,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1782,40 +1894,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h index b7c896df14..15ac614a86 100644 --- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h +++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 10, 10, 10 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -436,8 +439,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -468,6 +484,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -477,12 +510,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -519,6 +554,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -537,14 +574,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -577,6 +629,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -605,13 +661,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -658,23 +713,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -694,7 +744,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -719,7 +769,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -809,6 +859,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -919,7 +978,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -933,7 +992,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -948,46 +1019,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -996,24 +1079,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1028,8 +1109,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1039,7 +1120,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1048,27 +1129,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1232,6 +1320,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1248,13 +1377,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1423,4 +1559,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h index 1bb3ad1d1d..cc68b994e5 100644 --- a/Marlin/example_configurations/delta/generic/Configuration.h +++ b/Marlin/example_configurations/delta/generic/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -486,10 +490,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 121.5 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -637,7 +647,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -645,7 +655,7 @@ * * Enable this option for a probe connected to the Z Min endstop pin. */ -//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN /** * Z_MIN_PROBE_ENDSTOP @@ -666,7 +676,7 @@ * disastrous consequences. Use with caution and do your homework. * */ -#define Z_MIN_PROBE_ENDSTOP +//#define Z_MIN_PROBE_ENDSTOP /** * Probe Type @@ -750,14 +760,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 4000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -896,10 +908,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -919,7 +951,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -945,12 +977,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -981,6 +1008,24 @@ // Set the boundaries for probing (where the probe can reach). #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1036,7 +1081,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1049,8 +1096,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1110,13 +1157,70 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (200*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1148,7 +1252,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1293,11 +1397,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1425,8 +1529,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1534,11 +1638,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1646,7 +1752,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1704,17 +1816,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1730,11 +1842,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1749,22 +1861,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1777,40 +1889,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h index b7c896df14..15ac614a86 100644 --- a/Marlin/example_configurations/delta/generic/Configuration_adv.h +++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 10, 10, 10 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -436,8 +439,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -468,6 +484,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -477,12 +510,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -519,6 +554,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -537,14 +574,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -577,6 +629,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -605,13 +661,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -658,23 +713,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -694,7 +744,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -719,7 +769,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -809,6 +859,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -919,7 +978,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -933,7 +992,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -948,46 +1019,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -996,24 +1079,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1028,8 +1109,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1039,7 +1120,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1048,27 +1129,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1232,6 +1320,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1248,13 +1377,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1423,4 +1559,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h index edf3c48198..826129409e 100644 --- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -428,12 +431,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -486,10 +490,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 78.0 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -637,7 +647,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -750,14 +760,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 4000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -899,10 +911,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -922,7 +954,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -948,12 +980,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -984,6 +1011,24 @@ // Set the boundaries for probing (where the probe can reach). #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1039,7 +1084,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1052,8 +1099,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1113,13 +1160,70 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (200*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1151,7 +1255,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1296,11 +1400,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1428,8 +1532,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1537,11 +1641,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1649,7 +1755,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1707,17 +1819,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1733,11 +1845,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1752,22 +1864,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1780,40 +1892,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h index b7c896df14..15ac614a86 100644 --- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h +++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 10, 10, 10 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -436,8 +439,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -468,6 +484,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -477,12 +510,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -519,6 +554,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -537,14 +574,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -577,6 +629,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -605,13 +661,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -658,23 +713,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -694,7 +744,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -719,7 +769,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -809,6 +859,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -919,7 +978,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -933,7 +992,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -948,46 +1019,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -996,24 +1079,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1028,8 +1109,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1039,7 +1120,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1048,27 +1129,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1232,6 +1320,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1248,13 +1377,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1423,4 +1559,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h index e564fa8e35..490f4bb879 100644 --- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h @@ -41,7 +41,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -140,6 +140,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -340,8 +343,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX 125 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX 125 // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -351,7 +355,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 50 // 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 K1 0.95 //smoothing factor within the PID // Kossel Pro #define DEFAULT_Kp 19.30 @@ -414,12 +417,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -472,10 +476,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 110.0 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -630,7 +640,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -746,14 +756,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -899,10 +911,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -922,7 +954,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -948,12 +980,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -984,6 +1011,24 @@ // Set the boundaries for probing (where the probe can reach). #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1039,7 +1084,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1052,8 +1099,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1113,13 +1160,70 @@ #define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (200*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1151,7 +1255,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1296,11 +1400,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1428,8 +1532,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1537,11 +1641,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1649,7 +1755,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1707,17 +1819,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1733,11 +1845,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1752,22 +1864,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1780,40 +1892,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h index 9a519ec175..e2648ea97e 100644 --- a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h +++ b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -53,31 +53,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -91,13 +96,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -128,6 +127,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -262,48 +264,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -350,12 +353,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 10, 10, 10 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -441,8 +444,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -473,6 +489,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -482,12 +515,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -524,6 +559,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -542,14 +579,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -582,6 +634,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -610,13 +666,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -663,23 +718,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -699,7 +749,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -724,7 +774,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -814,6 +864,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -924,7 +983,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -938,7 +997,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -953,46 +1024,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -1001,24 +1084,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1033,8 +1114,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1044,7 +1125,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1053,27 +1134,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1237,6 +1325,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1253,13 +1382,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1428,4 +1564,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h index 6107f8c52b..1e732d76a3 100644 --- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // oXis Kossel k800 XL @@ -432,12 +435,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -490,10 +494,16 @@ #if ENABLED(DELTA_AUTO_CALIBRATION) // set the default number of probe points : n*n (1 -> 7) #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + + // Enable and set these values based on results of 'G33 A' + //#define H_FACTOR 1.01 + //#define R_FACTOR 2.61 + //#define A_FACTOR 0.87 + #endif #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) - // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + // Set the radius for the calibration probe points - max 0.9 * DELTA_PRINTABLE_RADIUS for non-eccentric probes #define DELTA_CALIBRATION_RADIUS 121.5 // mm // Set the steprate for papertest probing #define PROBE_MANUALLY_STEP 0.025 @@ -649,7 +659,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -657,7 +667,7 @@ * * Enable this option for a probe connected to the Z Min endstop pin. */ -//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN /** * Z_MIN_PROBE_ENDSTOP @@ -678,7 +688,7 @@ * disastrous consequences. Use with caution and do your homework. * */ -#define Z_MIN_PROBE_ENDSTOP +//#define Z_MIN_PROBE_ENDSTOP /** * Probe Type @@ -762,14 +772,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe @@ -908,10 +920,30 @@ #define Y_MAX_POS DELTA_PRINTABLE_RADIUS #define Z_MAX_POS MANUAL_Z_HOME_POS -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds //#define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -931,7 +963,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -957,12 +989,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -993,6 +1020,24 @@ // Set the boundaries for probing (where the probe can reach). #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -1048,7 +1093,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -1061,8 +1108,8 @@ #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1122,13 +1169,70 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Delta only homes to Z #define HOMING_FEEDRATE_Z (60*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1160,7 +1264,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1305,11 +1409,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1437,8 +1541,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1546,11 +1650,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1658,7 +1764,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1716,17 +1828,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1742,11 +1854,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1761,22 +1873,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1789,40 +1901,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h index 0c04e6d921..94b0bb8022 100644 --- a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h +++ b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 2 #define Y_HOME_BUMP_MM 2 #define Z_HOME_BUMP_MM 2 // deltas need the same for all three axes -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -436,8 +439,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -468,6 +484,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -477,12 +510,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -519,6 +554,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -537,14 +574,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -577,6 +629,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -605,13 +661,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -658,23 +713,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -694,7 +744,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -719,7 +769,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -809,6 +859,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -919,7 +978,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -933,7 +992,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -948,46 +1019,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -996,24 +1079,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1028,8 +1109,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1039,7 +1120,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1048,27 +1129,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1232,6 +1320,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1248,13 +1377,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1423,4 +1559,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration.h b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration.h index 3fe6e47f58..85a0b152fc 100644 --- a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration.h +++ b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -141,6 +141,9 @@ // :[1, 2, 3, 4, 5] #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 @@ -344,8 +347,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -355,7 +359,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -441,12 +444,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -586,7 +590,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -694,19 +698,21 @@ */ #define X_PROBE_OFFSET_FROM_EXTRUDER -17 // X offset: -left +right [of the nozzle] #define Y_PROBE_OFFSET_FROM_EXTRUDER -10 // Y offset: -front +behind [the nozzle] -#define Z_PROBE_OFFSET_FROM_EXTRUDER -1.027 // Z offset: -below +above [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.25 // Z offset: -below +above [the nozzle] // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 7500 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -799,10 +805,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 500 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds //#define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -822,7 +848,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -848,12 +874,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -880,6 +901,24 @@ // 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 + + // 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 // Enable G26 mesh validation + #if ENABLED(G26_MESH_VALIDATION) + #define MESH_TEST_NOZZLE_SIZE 0.5 // (mm) Diameter of primary nozzle. + #define MESH_TEST_LAYER_HEIGHT 0.3 // (mm) Default layer height for the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -935,7 +974,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 45 // Mesh inset margin on print area + #define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 45 // Mesh inset margin on print area #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 @@ -946,8 +987,8 @@ #define UBL_PROBE_PT_3_X 348 #define UBL_PROBE_PT_3_Y 211 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -1007,14 +1048,71 @@ #define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2 - 4) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2 + 4) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2 - 4) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2 + 4) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (60*60) #define HOMING_FEEDRATE_Z (14*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1046,7 +1144,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1191,11 +1289,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1323,8 +1421,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1432,11 +1530,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1544,7 +1644,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1602,17 +1708,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1628,11 +1734,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1647,22 +1753,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ #define NUM_SERVOS 2 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1675,40 +1781,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h index 7bbc33476d..c9af3121d1 100644 --- a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h +++ b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 50 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 3 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 50 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + #define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -601,15 +657,14 @@ */ #define BABYSTEPPING #if ENABLED(BABYSTEPPING) - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. - //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way + #define BABYSTEP_MULTIPLICATOR 3 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1422,4 +1558,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h index 8e530c5497..fc328d5178 100644 --- a/Marlin/example_configurations/makibox/Configuration.h +++ b/Marlin/example_configurations/makibox/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -431,12 +434,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -576,7 +580,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -689,14 +693,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -788,10 +794,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 86 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -811,7 +837,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -837,12 +863,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -869,6 +890,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -924,7 +963,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -935,8 +976,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -996,14 +1037,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY 1500 #define HOMING_FEEDRATE_Z (2*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1035,7 +1133,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1180,13 +1278,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1312,8 +1410,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1421,11 +1519,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1533,7 +1633,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1591,17 +1697,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1617,11 +1723,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1636,22 +1742,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1664,40 +1770,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h index e8188d6615..a7d733d22a 100644 --- a/Marlin/example_configurations/makibox/Configuration_adv.h +++ b/Marlin/example_configurations/makibox/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 4 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). //#define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h index d27812f50b..757b40d413 100644 --- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h +++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it // J-Head Mk V-B @@ -417,12 +420,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -568,7 +572,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -681,14 +685,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -780,10 +786,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 120 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -803,7 +829,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -829,12 +855,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -861,6 +882,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -916,7 +955,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -927,8 +968,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -988,14 +1029,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1027,7 +1125,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1172,13 +1270,13 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ -//#define LCD_LANGUAGE en +#define LCD_LANGUAGE en /** * LCD Character Set @@ -1304,8 +1402,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1413,11 +1511,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1525,7 +1625,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1583,17 +1689,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1609,11 +1715,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1628,22 +1734,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1656,40 +1762,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h index 6dc73d6216..8d6e2e1ed3 100644 --- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h +++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,9 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +259,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +348,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 1 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -434,8 +437,21 @@ //#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 -// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +// Use an I2C based DIGIPOT (e.g., Azteeg X3 Pro) //#define DIGIPOT_I2C +#if ENABLED(DIGIPOT_I2C) && !defined(DIGIPOT_I2C_ADDRESS_A) + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (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 + //#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS @@ -466,6 +482,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +508,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +552,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +572,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +627,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +659,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +711,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +742,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +767,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +857,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +976,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +990,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1017,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1077,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1107,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1118,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1127,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1318,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1375,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1557,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/example_configurations/wt150/Configuration.h b/Marlin/example_configurations/wt150/Configuration.h index b285ac0e57..4642755bdf 100644 --- a/Marlin/example_configurations/wt150/Configuration.h +++ b/Marlin/example_configurations/wt150/Configuration.h @@ -37,7 +37,7 @@ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#define CONFIGURATION_H_VERSION 010100 +#define CONFIGURATION_H_VERSION 010107 //=========================================================================== //============================= Getting Started ============================= @@ -136,6 +136,9 @@ // :[1, 2, 3, 4, 5] #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 3.0 + // For Cyclops or any "multi-extruder" that shares a single nozzle. //#define SINGLENOZZLE @@ -336,8 +339,9 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP -#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within the PID #if ENABLED(PIDTEMP) //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. //#define PID_DEBUG // Sends debug data to the serial port. @@ -347,7 +351,6 @@ // Set/get with gcode: M301 E[extruder number, 0-2] #define PID_FUNCTIONAL_RANGE 10 // 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 K1 0.95 //smoothing factor within the PID // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it @@ -433,12 +436,13 @@ //=========================================================================== /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the * details can be tuned in Configuration_adv.h @@ -578,7 +582,7 @@ // @section probes // -// See http://marlinfw.org/configuration/probes.html +// See http://marlinfw.org/docs/configuration/probes.html // /** @@ -691,14 +695,16 @@ // X and Y axis travel speed (mm/m) between probes #define XY_PROBE_SPEED 8000 -// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +// Speed for the first approach when double-probing (MULTIPLE_PROBING == 2) #define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z // Speed for the "accurate" probe of each point #define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) -// Use double touch for probing -//#define PROBE_DOUBLE_TOUCH +// The number of probes to perform at each point. +// Set to 2 for a fast/slow probe, using the second probe result. +// Set to 3 or more for slow probes, averaging the results. +//#define MULTIPLE_PROBING 2 /** * Z probes require clearance when deploying, stowing, and moving between @@ -790,10 +796,30 @@ #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 143.0 -// If enabled, axes won't move below MIN_POS in response to movement commands. +/** + * 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 curtail movement below minimum coordinate bounds #define MIN_SOFTWARE_ENDSTOPS -// If enabled, axes won't move above MAX_POS in response to movement commands. +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z +#endif + +// Max software endstops curtail movement above 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 +#endif /** * Filament Runout Sensor @@ -813,7 +839,7 @@ //=========================================================================== //=============================== Bed Leveling ============================== //=========================================================================== -// @section bedlevel +// @section calibrate /** * Choose one of the options below to enable G29 Bed Leveling. The parameters @@ -839,12 +865,7 @@ * - 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. Currently, UBL is only checked out - * for Cartesian Printers. That said, it was primarily designed to correct - * poor quality Delta Printers. If you feel adventurous and have a Delta, - * please post an issue if something doesn't work correctly. Initially, - * you will need to set a reduced bed size so you have a rectangular area - * to test on. + * Validation and Mesh Editing systems. * * - MESH_BED_LEVELING * Probe a grid manually @@ -871,6 +892,24 @@ // 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 + + // 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 // Enable 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 the G26 Mesh Validation Tool. + #define MESH_TEST_HOTEND_TEMP 205.0 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool. + #define MESH_TEST_BED_TEMP 60.0 // (°C) Default bed temperature for the G26 Mesh Validation Tool. + #endif + #endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) @@ -926,7 +965,9 @@ //========================= Unified Bed Leveling ============================ //=========================================================================== - #define UBL_MESH_INSET 1 // Mesh inset margin on print area + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Mesh inset margin on print area #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 @@ -937,8 +978,8 @@ #define UBL_PROBE_PT_3_X 180 #define UBL_PROBE_PT_3_Y 20 - #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation #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 #elif ENABLED(MESH_BED_LEVELING) @@ -998,14 +1039,71 @@ //#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axis (G28). - #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2) // X point for Z homing when homing all axes (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axes (G28). #endif // Homing speeds (mm/m) #define HOMING_FEEDRATE_XY (50*60) #define HOMING_FEEDRATE_Z (4*60) +// @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 default skew factors directly here + // to override the above measurements: + #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 + #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 =========================== //============================================================================= @@ -1037,7 +1135,7 @@ // // M100 Free Memory Watcher // -//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose +//#define M100_FREE_MEMORY_WATCHER // Add M100 (Free Memory Watcher) to debug memory usage // // G20/G21 Inch mode support @@ -1182,11 +1280,11 @@ * * Select the language to display on the LCD. These languages are available: * - * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, - * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, fr_utf8, gl, + * hr, it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, * tr, uk, zh_CN, zh_TW, test * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'fr_utf8':'French (UTF8)', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } */ #define LCD_LANGUAGE en @@ -1314,8 +1412,8 @@ // Note: Test audio output with the G-Code: // M300 S P // -//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 -//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 // // CONTROLLER TYPE: Standard @@ -1423,11 +1521,13 @@ //#define CARTESIO_UI // -// ANET_10 Controller supported displays. +// ANET and Tronxy Controller supported displays. // -//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. +//#define ZONESTAR_LCD // 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. Pressing any button clears it up. + // This is a LCD2004 display with 5 analog buttons. + //#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 // A clone of the RepRapDiscount full graphics display but with // different pins/wiring (see pins_ANET_10.h). @@ -1535,7 +1635,13 @@ // // Tiny, but very sharp OLED display // -//#define MKS_12864OLED +//#define MKS_12864OLED // Uses the SH1106 controller (default) +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// Silvergate GLCD controller +// http://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER //============================================================================= //=============================== Extra Features ============================== @@ -1593,17 +1699,17 @@ * 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 overall brightness parameters is also available + * For Neopixel LED an overall brightness parameter is also available. * * *** CAUTION *** * LED Strips require a MOFSET 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! - * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino - * cannot handle such current, separate 5V power supply must be used + * NOTE: A separate 5V power supply is required! The Neopixel LED needs + * more current than the Arduino 5V linear regulator can produce. * *** CAUTION *** * - * LED type. This options are mutualy exclusive. Uncomment only one. + * LED Type. Enable only one of the following two options. * */ //#define RGB_LED @@ -1619,11 +1725,11 @@ // Support for Adafruit Neopixel LED driver //#define NEOPIXEL_LED #if ENABLED(NEOPIXEL_LED) - #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h) #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) - #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip - #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip + #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 #endif @@ -1638,22 +1744,22 @@ * - Change to green once print has finished * - Turn off after the print has finished and the user has pushed a button */ -#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) #define PRINTER_EVENT_LEDS #endif -/*********************************************************************\ -* R/C SERVO support -* Sponsored by TrinityLabs, Reworked by codexmas -**********************************************************************/ +/** + * R/C SERVO support + * Sponsored by TrinityLabs, Reworked by codexmas + */ -// Number of servos -// -// If you select a configuration below, this will receive a default value and does not need to be set manually -// set it manually if you have more servos than extruders and wish to manually control some -// leaving it undefined or defining as 0 will disable the servo subsystem -// If unsure, leave commented / disabled -// +/** + * 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. + * Leave undefined or set to 0 to entirely disable the servo subsystem. + */ //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. @@ -1666,40 +1772,4 @@ // With this option servos are powered only during movement, then turned off to prevent jitter. //#define DEACTIVATE_SERVOS_AFTER_MOVE -/** - * 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 - -#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading - #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading - #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 - #endif // CONFIGURATION_H diff --git a/Marlin/example_configurations/wt150/Configuration_adv.h b/Marlin/example_configurations/wt150/Configuration_adv.h index aed0fee489..0d936d3a33 100644 --- a/Marlin/example_configurations/wt150/Configuration_adv.h +++ b/Marlin/example_configurations/wt150/Configuration_adv.h @@ -32,7 +32,7 @@ */ #ifndef CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H -#define CONFIGURATION_ADV_H_VERSION 010100 +#define CONFIGURATION_ADV_H_VERSION 010107 // @section temperature @@ -48,31 +48,36 @@ #endif /** - * Thermal Protection protects your printer from damage and fire if a - * thermistor falls out or temperature sensors fail in any way. + * 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 or a temperature sensor fails, - * Marlin can no longer sense the actual temperature. Since a disconnected - * thermistor reads as a low temperature, the firmware will keep the heater on. + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. * * The solution: Once the temperature reaches the target, start observing. - * If the temperature stays too far below the target (hysteresis) for too long (period), - * the firmware will halt the machine as a safety precaution. + * If 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 you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD */ #if ENABLED(THERMAL_PROTECTION_HOTENDS) #define THERMAL_PROTECTION_PERIOD 40 // Seconds #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius /** - * Whenever an M104 or M109 increases the target temperature the firmware will wait for the - * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, - * but only if the current temperature is far enough below the target for a reliable test. + * 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 below 2. + * 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 20 // Seconds #define WATCH_TEMP_INCREASE 2 // Degrees Celsius @@ -86,13 +91,7 @@ #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius /** - * Whenever an M140 or M190 increases the target temperature the firmware will wait for the - * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE - * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, - * but only if the current temperature is far enough below the target for a reliable test. - * - * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease - * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + * As described above, except for the bed (M140/M190/M303). */ #define WATCH_BED_TEMP_PERIOD 60 // Seconds #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius @@ -123,6 +122,12 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +// Show extra position information in M114 +//#define M114_DETAIL + +// Show extra position information in M114 +//#define M114_DETAIL + // Show Temperature ADC value // Enable for M105 to include ADC values read from temperature sensors. //#define SHOW_TEMP_ADC_VALUES @@ -257,48 +262,49 @@ //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. -// Dual X Steppers -// Uncomment this option to drive two X axis motors. -// The next unused E driver will be assigned to the second X stepper. +/** + * Dual Steppers / Dual Endstops + * + * This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes. + * + * For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to + * spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop + * set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug + * that should be used for the second endstop. Extra endstops will appear in the output of 'M119'. + * + * Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors + * this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error + * in X2. Dual endstop offsets can be set at runtime with 'M666 X Y Z'. + */ + //#define X_DUAL_STEPPER_DRIVERS #if ENABLED(X_DUAL_STEPPER_DRIVERS) - // Set true if the two X motors need to rotate in opposite directions - #define INVERT_X2_VS_X_DIR true + #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions + //#define X_DUAL_ENDSTOPS + #if ENABLED(X_DUAL_ENDSTOPS) + #define X2_USE_ENDSTOP _XMAX_ + #define X_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// Dual Y Steppers -// Uncomment this option to drive two Y axis motors. -// The next unused E driver will be assigned to the second Y stepper. //#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) - // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR true + #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions + //#define Y_DUAL_ENDSTOPS + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y2_USE_ENDSTOP _YMAX_ + #define Y_DUAL_ENDSTOPS_ADJUSTMENT 0 + #endif #endif -// A single Z stepper driver is usually used to drive 2 stepper motors. -// Uncomment this option to use a separate stepper driver for each Z axis motor. -// The next unused E driver will be assigned to the second Z stepper. //#define Z_DUAL_STEPPER_DRIVERS - #if ENABLED(Z_DUAL_STEPPER_DRIVERS) - - // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. - // That way the machine is capable to align the bed during home, since both Z steppers are homed. - // There is also an implementation of M666 (software endstops adjustment) to this feature. - // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. - // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. - // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. - // Play a little bit with small adjustments (0.5mm) and check the behaviour. - // The M119 (endstops report) will start reporting the Z2 Endstop as well. - //#define Z_DUAL_ENDSTOPS - #if ENABLED(Z_DUAL_ENDSTOPS) #define Z2_USE_ENDSTOP _XMAX_ - #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 #endif - -#endif // Z_DUAL_STEPPER_DRIVERS +#endif // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which @@ -345,12 +351,12 @@ // @section homing -//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +// Homing hits each endstop, retracts by these distances, then does a slower bump. #define X_HOME_BUMP_MM 5 #define Y_HOME_BUMP_MM 5 #define Z_HOME_BUMP_MM 2 -#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) -//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. +#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME // If homing includes X and Y, do a diagonal move initially // When G28 is called, this option will make Y home before X //#define HOME_Y_BEFORE_X @@ -466,6 +472,23 @@ // The timeout (in ms) to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 +/** + * LED Control Menu + * Enable this feature to 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 + #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 +#endif // LED_CONTROL_MENU + #if ENABLED(SDSUPPORT) // Some RAMPS and other boards don't detect when an SD card is inserted. You can work @@ -475,12 +498,14 @@ // Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER). #define SD_DETECT_INVERTED - #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. - #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. - // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. - // using: + // 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 + + // Add an option in the menu to run all auto#.g files //#define MENU_ADDAUTOSTART /** @@ -517,6 +542,8 @@ #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. #endif // Show a progress bar on HD44780 LCDs for SD printing @@ -535,14 +562,29 @@ //#define LCD_PROGRESS_BAR_TEST #endif + // Add an 'M73' G-code to set the current percentage + //#define LCD_SET_PROGRESS_MANUALLY + // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - // This option allows you to abort SD printing when any endstop is triggered. - // This feature must be enabled with "M540 S1" or from the LCD menu. - // To have any effect, endstops must be enabled during SD printing. + // Enable this option to scroll long filenames in the SD card menu + //#define SCROLL_LONG_FILENAMES + + /** + * This option allows you to abort SD printing when any endstop is triggered. + * This feature must be enabled with "M540 S1" or from the LCD menu. + * To have any effect, endstops must be enabled during SD printing. + */ //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + /** + * This option makes it easier to print the same SD Card file again. + * On print completion the LCD Menu will open with the file selected. + * You can just click to start the print, or navigate elsewhere. + */ + //#define SD_REPRINT_LAST_SELECTED_FILE + #endif // SDSUPPORT /** @@ -575,6 +617,10 @@ // 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 + + // Swap the CW/CCW indicators in the graphics overlay + //#define OVERLAY_GFX_REVERSE + #endif // DOGLCD // @section safety @@ -603,13 +649,12 @@ #if ENABLED(BABYSTEPPING) //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion. + #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion. //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. // Note: Extra time may be added to mitigate controller latency. //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators #endif // @section extruder @@ -656,23 +701,18 @@ // @section leveling -// Default mesh area is an area with an inset margin on the print area. -// Below are the macros that are used to define the borders for the mesh area, -// made available here for specialized needs, ie dual extruder setup. -#if ENABLED(MESH_BED_LEVELING) - #define MESH_MIN_X MESH_INSET - #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) - #define MESH_MIN_Y MESH_INSET - #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #define UBL_MESH_MIN_X UBL_MESH_INSET - #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) - #define UBL_MESH_MIN_Y UBL_MESH_INSET - #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) +#if ENABLED(DELTA) && !defined(DELTA_PROBEABLE_RADIUS) + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS +#elif IS_SCARA && !defined(SCARA_PRINTABLE_RADIUS) + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) +#endif - // If this is defined, the currently active mesh will be saved in the - // current slot on M500. - #define UBL_SAVE_ACTIVE_ON_M500 +#if ENABLED(MESH_BED_LEVELING) || ENABLED(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 // @section extras @@ -692,7 +732,7 @@ //#define BEZIER_CURVE_SUPPORT // G38.2 and G38.3 Probe Target -// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +// Set MULTIPLE_PROBING if you want G38 to double touch //#define G38_PROBE_TARGET #if ENABLED(G38_PROBE_TARGET) #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) @@ -717,7 +757,7 @@ // @section hidden // The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2 (e.g. 8, 16, 32) because shifts and ors are used to do the ring-buffering. #if ENABLED(SDSUPPORT) #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -807,6 +847,15 @@ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) #endif +/** + * 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 + /** * Advanced Pause * Experimental feature for filament change support and for parking the nozzle when paused. @@ -917,7 +966,7 @@ #endif -// @section TMC2130 +// @section TMC2130, TMC2208 /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. @@ -931,7 +980,19 @@ */ //#define HAVE_TMC2130 -#if ENABLED(HAVE_TMC2130) +/** + * Enable this for SilentStepStick Trinamic TMC2208 UART-configurable stepper drivers. + * Connect #_SERIAL_TX_PIN to the driver side PDN_UART pin. + * To use the reading capabilities, also connect #_SERIAL_RX_PIN + * to #_SERIAL_TX_PIN with a 1K resistor. + * The drivers can also be used with hardware serial. + * + * You'll also need the TMC2208Stepper Arduino library + * (https://github.com/teemuatlut/TMC2208Stepper). + */ +//#define HAVE_TMC2208 + +#if ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -946,46 +1007,58 @@ //#define E3_IS_TMC2130 //#define E4_IS_TMC2130 + //#define X_IS_TMC2208 + //#define X2_IS_TMC2208 + //#define Y_IS_TMC2208 + //#define Y2_IS_TMC2208 + //#define Z_IS_TMC2208 + //#define Z2_IS_TMC2208 + //#define E0_IS_TMC2208 + //#define E1_IS_TMC2208 + //#define E2_IS_TMC2208 + //#define E3_IS_TMC2208 + //#define E4_IS_TMC2208 + /** * Stepper driver settings */ #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256 - #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_CURRENT 800 // rms current in mA. Multiply by 1.41 for peak current. #define X_MICROSTEPS 16 // 0..256 - #define Y_CURRENT 1000 + #define Y_CURRENT 800 #define Y_MICROSTEPS 16 - #define Z_CURRENT 1000 + #define Z_CURRENT 800 #define Z_MICROSTEPS 16 - //#define X2_CURRENT 1000 - //#define X2_MICROSTEPS 16 + #define X2_CURRENT 800 + #define X2_MICROSTEPS 16 - //#define Y2_CURRENT 1000 - //#define Y2_MICROSTEPS 16 + #define Y2_CURRENT 800 + #define Y2_MICROSTEPS 16 - //#define Z2_CURRENT 1000 - //#define Z2_MICROSTEPS 16 + #define Z2_CURRENT 800 + #define Z2_MICROSTEPS 16 - //#define E0_CURRENT 1000 - //#define E0_MICROSTEPS 16 + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 - //#define E1_CURRENT 1000 - //#define E1_MICROSTEPS 16 + #define E1_CURRENT 800 + #define E1_MICROSTEPS 16 - //#define E2_CURRENT 1000 - //#define E2_MICROSTEPS 16 + #define E2_CURRENT 800 + #define E2_MICROSTEPS 16 - //#define E3_CURRENT 1000 - //#define E3_MICROSTEPS 16 + #define E3_CURRENT 800 + #define E3_MICROSTEPS 16 - //#define E4_CURRENT 1000 - //#define E4_MICROSTEPS 16 + #define E4_CURRENT 800 + #define E4_MICROSTEPS 16 /** * Use Trinamic's ultra quiet stepping mode. @@ -994,24 +1067,22 @@ #define STEALTHCHOP /** - * Let Marlin automatically control stepper current. - * This is still an experimental feature. - * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, - * then decrease current by CURRENT_STEP until temperature prewarn is cleared. - * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * Monitor Trinamic TMC2130 and TMC2208 drivers for error conditions, + * like overtemperature and short to ground. TMC2208 requires hardware serial. + * In the case of overtemperature Marlin can decrease the driver current until 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. - * M906 S1 - Start adjusting current - * M906 S0 - Stop adjusting current * M911 - Report stepper driver overtemperature pre-warn condition. * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 S0/1 - Report driver parameters (Requires TMC_DEBUG) */ - //#define AUTOMATIC_CURRENT_CONTROL + //#define MONITOR_DRIVER_STATUS - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) - #define CURRENT_STEP 50 // [mA] - #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR #endif /** @@ -1026,8 +1097,8 @@ #define X2_HYBRID_THRESHOLD 100 #define Y_HYBRID_THRESHOLD 100 #define Y2_HYBRID_THRESHOLD 100 - #define Z_HYBRID_THRESHOLD 4 - #define Z2_HYBRID_THRESHOLD 4 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 #define E0_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30 @@ -1037,7 +1108,7 @@ /** * Use stallGuard2 to sense an obstacle and trigger an endstop. * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. - * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * X and Y homing will always be done in spreadCycle mode. * * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. * Higher values make the system LESS sensitive. @@ -1046,27 +1117,34 @@ * It is advised to set X/Y_HOME_BUMP_MM to 0. * M914 X/Y to live tune the setting */ - //#define SENSORLESS_HOMING + //#define SENSORLESS_HOMING // TMC2130 only #if ENABLED(SENSORLESS_HOMING) - #define X_HOMING_SENSITIVITY 19 - #define Y_HOMING_SENSITIVITY 19 + #define X_HOMING_SENSITIVITY 8 + #define Y_HOMING_SENSITIVITY 8 #endif + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continous 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/TMC2130Stepper + * https://github.com/teemuatlut/TMC2208Stepper * * Example: - * #define TMC2130_ADV() { \ + * #define TMC_ADV() { \ * stepperX.diag0_temp_prewarn(1); \ - * stepperX.interpolate(0); \ + * stepperY.interpolate(0); \ * } */ - #define TMC2130_ADV() { } + #define TMC_ADV() { } -#endif // HAVE_TMC2130 +#endif // TMC2130 || TMC2208 // @section L6470 @@ -1230,6 +1308,47 @@ //#define SPEED_POWER_MAX 100 // 0-100% #endif +/** + * 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 + +/** + * 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 + /** * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins */ @@ -1246,13 +1365,20 @@ #define EXTENDED_CAPABILITIES_REPORT /** - * 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. + * Disable all Volumetric extrusion options */ -//#define VOLUMETRIC_DEFAULT_ON +//#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. + */ + //#define VOLUMETRIC_DEFAULT_ON +#endif /** * Enable this option for a leaner build of Marlin that removes all @@ -1421,4 +1547,17 @@ // tweaks made to the configuration are affecting the printer in real-time. #endif +/** + * NanoDLP Sync support + * + * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp" + * string to enable synchronization with DLP projector exposure. This change will allow to use + * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move. + // Default behaviour is limited to Z axis only. +#endif + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/gcode.cpp b/Marlin/gcode.cpp index edeb00e226..fd26aaea16 100644 --- a/Marlin/gcode.cpp +++ b/Marlin/gcode.cpp @@ -32,6 +32,8 @@ // Must be declared for allocation and to satisfy the linker // Zero values need no initialization. +bool GCodeParser::volumetric_enabled; + #if ENABLED(INCH_MODE_SUPPORT) float GCodeParser::linear_unit_factor, GCodeParser::volumetric_unit_factor; #endif @@ -150,7 +152,7 @@ void GCodeParser::parse(char *p) { #endif // Only use string_arg for these M codes - if (letter == 'M') switch (codenum) { case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return; default: break; } + if (letter == 'M') switch (codenum) { case 23: case 28: case 30: case 117: case 928: string_arg = p; return; default: break; } #if ENABLED(DEBUG_GCODE_PARSER) const bool debug = codenum == 800; @@ -162,9 +164,10 @@ void GCodeParser::parse(char *p) { * Most codes ignore 'string_arg', but those that want a string will get the right pointer. * The following loop assigns the first "parameter" having no numeric value to 'string_arg'. * This allows M0/M1 with expire time to work: "M0 S5 You Win!" + * For 'M118' you must use 'E1' and 'A1' rather than just 'E' or 'A' */ string_arg = NULL; - while (char code = *p++) { // Get the next parameter. A NUL ends the loop + while (const char code = *p++) { // Get the next parameter. A NUL ends the loop // Special handling for M32 [P] !/path/to/file.g# // The path must be the last parameter @@ -185,12 +188,20 @@ void GCodeParser::parse(char *p) { if (PARAM_TEST) { while (*p == ' ') p++; // Skip spaces between parameters & values - const bool has_num = DECIMAL_SIGNED(*p); // The parameter has a number [-+0-9.] + + const bool has_num = NUMERIC(p[0]) // [0-9] + || (p[0] == '.' && NUMERIC(p[1])) // .[0-9] + || ( + (p[0] == '-' || p[0] == '+') && ( // [-+] + NUMERIC(p[1]) // [0-9] + || (p[1] == '.' && NUMERIC(p[2])) // .[0-9] + ) + ); #if ENABLED(DEBUG_GCODE_PARSER) if (debug) { - SERIAL_ECHOPAIR("Got letter ", code); // DEBUG - SERIAL_ECHOPAIR(" at index ", (int)(p - command_ptr - 1)); // DEBUG + SERIAL_ECHOPAIR("Got letter ", code); + SERIAL_ECHOPAIR(" at index ", (int)(p - command_ptr - 1)); if (has_num) SERIAL_ECHOPGM(" (has_num)"); } #endif @@ -207,11 +218,13 @@ void GCodeParser::parse(char *p) { #endif #if ENABLED(FASTER_GCODE_PARSER) + { set(code, has_num ? p : NULL // Set parameter exists and pointer (NULL for no number) #if ENABLED(DEBUG_GCODE_PARSER) , debug #endif ); + } #endif } else if (!string_arg) { // Not A-Z? First time, keep as the string_arg @@ -221,13 +234,33 @@ void GCodeParser::parse(char *p) { #endif } - if (!WITHIN(*p, 'A', 'Z')) { - while (*p && NUMERIC(*p)) p++; // Skip over the value section of a parameter + if (!WITHIN(*p, 'A', 'Z')) { // Another parameter right away? + while (*p && DECIMAL_SIGNED(*p)) p++; // Skip over the value section of a parameter while (*p == ' ') p++; // Skip over all spaces } } } +#if ENABLED(CNC_COORDINATE_SYSTEMS) + + // Parse the next parameter as a new command + bool GCodeParser::chain() { + #if ENABLED(FASTER_GCODE_PARSER) + char *next_command = command_ptr; + if (next_command) { + while (*next_command && *next_command != ' ') ++next_command; + while (*next_command == ' ') ++next_command; + if (!*next_command) next_command = NULL; + } + #else + const char *next_command = command_args; + #endif + if (next_command) parse(next_command); + return !!next_command; + } + +#endif // CNC_COORDINATE_SYSTEMS + void GCodeParser::unknown_command_error() { SERIAL_ECHO_START(); SERIAL_ECHOPAIR(MSG_UNKNOWN_COMMAND, command_ptr); diff --git a/Marlin/gcode.h b/Marlin/gcode.h index 36549b851f..3ad2113908 100644 --- a/Marlin/gcode.h +++ b/Marlin/gcode.h @@ -44,10 +44,6 @@ #include "serial.h" #endif -#if ENABLED(INCH_MODE_SUPPORT) - extern bool volumetric_enabled; -#endif - /** * GCode parser * @@ -76,6 +72,8 @@ public: // Global states for GCode-level units features + static bool volumetric_enabled; + #if ENABLED(INCH_MODE_SUPPORT) static float linear_unit_factor, volumetric_unit_factor; #endif @@ -169,6 +167,11 @@ public: // This uses 54 bytes of SRAM to speed up seen/value static void parse(char * p); + #if ENABLED(CNC_COORDINATE_SYSTEMS) + // Parse the next parameter as a new command + static bool chain(); + #endif + // The code value pointer was set FORCE_INLINE static bool has_value() { return value_ptr != NULL; } @@ -307,7 +310,7 @@ public: // Provide simple value accessors with default option FORCE_INLINE static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; } - FORCE_INLINE static bool boolval(const char c, const bool dval=false) { return seen(c) ? value_bool() : dval; } + FORCE_INLINE static bool boolval(const char c) { return seenval(c) ? value_bool() : seen(c); } FORCE_INLINE static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; } FORCE_INLINE static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; } FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; } diff --git a/Marlin/language.h b/Marlin/language.h index 0ff6badefb..351b9dc33d 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -61,6 +61,7 @@ // eu Basque-Euskera // fi Finnish // fr French +// fr_utf8 French (UTF8) // gl Galician // hr Croatian // it Italian @@ -129,7 +130,6 @@ #define MSG_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: " #define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " #define MSG_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " -#define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: " #define MSG_FILE_PRINTED "Done printing file" #define MSG_BEGIN_FILE_LIST "Begin file list" #define MSG_END_FILE_LIST "End file list" @@ -144,18 +144,26 @@ #define MSG_BUSY_PROCESSING "busy: processing" #define MSG_BUSY_PAUSED_FOR_USER "busy: paused for user" #define MSG_BUSY_PAUSED_FOR_INPUT "busy: paused for input" +#define MSG_Z_MOVE_COMP "Z_move_comp" #define MSG_RESEND "Resend: " #define MSG_UNKNOWN_COMMAND "Unknown command: \"" #define MSG_ACTIVE_EXTRUDER "Active Extruder: " #define MSG_X_MIN "x_min: " #define MSG_X_MAX "x_max: " +#define MSG_X2_MIN "x2_min: " +#define MSG_X2_MAX "x2_max: " #define MSG_Y_MIN "y_min: " #define MSG_Y_MAX "y_max: " +#define MSG_Y2_MIN "y2_min: " +#define MSG_Y2_MAX "y2_max: " #define MSG_Z_MIN "z_min: " #define MSG_Z_MAX "z_max: " #define MSG_Z2_MIN "z2_min: " #define MSG_Z2_MAX "z2_max: " #define MSG_Z_PROBE "z_probe: " +#define MSG_PROBE_Z_OFFSET "Probe Z Offset" +#define MSG_SKEW_MIN "min_skew_factor: " +#define MSG_SKEW_MAX "max_skew_factor: " #define MSG_FILAMENT_RUNOUT_SENSOR "filament: " #define MSG_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" #define MSG_ERR_M355_NONE "No case light" diff --git a/Marlin/language_an.h b/Marlin/language_an.h index be3b04b3b0..3ab4d1d250 100644 --- a/Marlin/language_an.h +++ b/Marlin/language_an.h @@ -31,6 +31,7 @@ #define LANGUAGE_AN_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME _UxGT(" parada.") #define MSG_SD_INSERTED _UxGT("Tarcheta mesa") diff --git a/Marlin/language_de.h b/Marlin/language_de.h index c57605a078..4036a0dcfe 100644 --- a/Marlin/language_de.h +++ b/Marlin/language_de.h @@ -53,7 +53,7 @@ #define MSG_LEVEL_BED_WAITING _UxGT("Klick für Start") #define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nächste Koordinate") #define MSG_LEVEL_BED_DONE _UxGT("Fertig") -#define MSG_Z_FADE_HEIGHT _UxGT("Niv. Ausblendhöhe") +#define MSG_Z_FADE_HEIGHT _UxGT("Ausblendhöhe") #define MSG_SET_HOME_OFFSETS _UxGT("Setze Homeversatz") #define MSG_HOME_OFFSETS_APPLIED _UxGT("Homeversatz aktiv") #define MSG_SET_ORIGIN _UxGT("Setze Nullpunkt") //"G92 X0 Y0 Z0" commented out in ultralcd.cpp @@ -77,6 +77,8 @@ #define MSG_MOVE_AXIS _UxGT("Bewegen") #define MSG_BED_LEVELING _UxGT("Bett Nivellierung") #define MSG_LEVEL_BED _UxGT("Bett nivellieren") +#define MSG_LEVEL_CORNERS _UxGT("Ecken nivellieren") +#define MSG_NEXT_CORNER _UxGT("Nächste Ecke") #define MSG_EDITING_STOPPED _UxGT("Netzbearb. angeh.") #define MSG_USER_MENU _UxGT("Benutzer Menü") #define MSG_MOVING _UxGT("In Bewegung...") diff --git a/Marlin/language_en.h b/Marlin/language_en.h index 811b132fb4..879a6fa01a 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -30,6 +30,12 @@ #ifndef LANGUAGE_EN_H #define LANGUAGE_EN_H +#define en 1234 +#if LCD_LANGUAGE == en + #define NOT_EXTENDED_ISO10646_1_5X7 +#endif +#undef en + #ifndef WELCOME_MSG #define WELCOME_MSG MACHINE_NAME _UxGT(" ready.") #endif @@ -356,6 +362,64 @@ #define MSG_UBL_STEP_BY_STEP_MENU _UxGT("Step-By-Step UBL") #endif +#ifndef MSG_LED_CONTROL + #define MSG_LED_CONTROL _UxGT("LED Control") +#endif +#ifndef MSG_LEDS_ON + #define MSG_LEDS_ON _UxGT("Lights On") +#endif +#ifndef MSG_LEDS_OFF + #define MSG_LEDS_OFF _UxGT("Lights Off") +#endif +#ifndef MSG_LED_PRESETS + #define MSG_LED_PRESETS _UxGT("Light Presets") +#endif +#ifndef MSG_SET_LEDS_RED + #define MSG_SET_LEDS_RED _UxGT("Lights Red") +#endif +#ifndef MSG_SET_LEDS_ORANGE + #define MSG_SET_LEDS_ORANGE _UxGT("Lights Orange") +#endif +#ifndef MSG_SET_LEDS_YELLOW + #define MSG_SET_LEDS_YELLOW _UxGT("Lights Yellow") +#endif +#ifndef MSG_SET_LEDS_GREEN + #define MSG_SET_LEDS_GREEN _UxGT("Lights Green") +#endif +#ifndef MSG_SET_LEDS_BLUE + #define MSG_SET_LEDS_BLUE _UxGT("Lights Blue") +#endif +#ifndef MSG_SET_LEDS_INDIGO + #define MSG_SET_LEDS_INDIGO _UxGT("Lights Indigo") +#endif +#ifndef MSG_SET_LEDS_VIOLET + #define MSG_SET_LEDS_VIOLET _UxGT("Lights Violet") +#endif +#ifndef MSG_SET_LEDS_WHITE + #define MSG_SET_LEDS_WHITE _UxGT("Lights White") +#endif +#ifndef MSG_SET_LEDS_DEFAULT + #define MSG_SET_LEDS_DEFAULT _UxGT("Lights Default") +#endif +#ifndef MSG_CUSTOM_LEDS + #define MSG_CUSTOM_LEDS _UxGT("Custom Lights") +#endif +#ifndef MSG_INTENSITY_R + #define MSG_INTENSITY_R _UxGT("Red Intensity") +#endif +#ifndef MSG_INTENSITY_G + #define MSG_INTENSITY_G _UxGT("Green Intensity") +#endif +#ifndef MSG_INTENSITY_B + #define MSG_INTENSITY_B _UxGT("Blue Intensity") +#endif +#ifndef MSG_INTENSITY_W + #define MSG_INTENSITY_W _UxGT("White Intensity") +#endif +#ifndef MSG_LED_BRIGHTNESS + #define MSG_LED_BRIGHTNESS _UxGT("Brightness") +#endif + #ifndef MSG_MOVING #define MSG_MOVING _UxGT("Moving...") #endif @@ -398,6 +462,9 @@ #ifndef MSG_FAN_SPEED #define MSG_FAN_SPEED _UxGT("Fan speed") #endif +#ifndef MSG_EXTRA_FAN_SPEED + #define MSG_EXTRA_FAN_SPEED _UxGT("Extra fan speed") +#endif #ifndef MSG_FLOW #define MSG_FLOW _UxGT("Flow") #endif @@ -612,7 +679,10 @@ #define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") #endif #ifndef MSG_CONTROL_RETRACT_RECOVERF - #define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") + #define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVER_SWAPF + #define MSG_CONTROL_RETRACT_RECOVER_SWAPF _UxGT("S UnRet V") #endif #ifndef MSG_AUTORETRACT #define MSG_AUTORETRACT _UxGT("AutoRetr.") @@ -629,6 +699,9 @@ #ifndef MSG_ZPROBE_OUT #define MSG_ZPROBE_OUT _UxGT("Z probe out. bed") #endif +#ifndef MSG_SKEW_FACTOR + #define MSG_SKEW_FACTOR _UxGT("Skew Factor") +#endif #ifndef MSG_BLTOUCH #define MSG_BLTOUCH _UxGT("BLTouch") #endif @@ -740,8 +813,8 @@ #ifndef MSG_DELTA_HEIGHT_CALIBRATE #define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Set Delta Height") #endif -#ifndef MSG_DELTA_DIAG_ROG - #define MSG_DELTA_DIAG_ROG _UxGT("Diag Rod") +#ifndef MSG_DELTA_DIAG_ROD + #define MSG_DELTA_DIAG_ROD _UxGT("Diag Rod") #endif #ifndef MSG_DELTA_HEIGHT #define MSG_DELTA_HEIGHT _UxGT("Height") diff --git a/Marlin/language_es.h b/Marlin/language_es.h index 2983cf249f..248ecb1931 100644 --- a/Marlin/language_es.h +++ b/Marlin/language_es.h @@ -31,6 +31,7 @@ #define LANGUAGE_ES_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME _UxGT(" lista.") #define MSG_BACK _UxGT("Atras") diff --git a/Marlin/language_eu.h b/Marlin/language_eu.h index c4fe4ba490..5be54c5468 100644 --- a/Marlin/language_eu.h +++ b/Marlin/language_eu.h @@ -31,6 +31,7 @@ #define LANGUAGE_EU_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME _UxGT(" prest.") #define MSG_BACK _UxGT("Atzera") diff --git a/Marlin/language_fr.h b/Marlin/language_fr.h index d448cf917a..e89abcd5dd 100644 --- a/Marlin/language_fr.h +++ b/Marlin/language_fr.h @@ -30,17 +30,17 @@ #ifndef LANGUAGE_FR_H #define LANGUAGE_FR_H -#define MAPPER_C2C3 -#define DISPLAY_CHARSET_ISO10646_1 +#define MAPPER_NON +#define NOT_EXTENDED_ISO10646_1_5X7 -#define WELCOME_MSG MACHINE_NAME _UxGT(" prête.") +#define WELCOME_MSG MACHINE_NAME _UxGT(" prete.") #define MSG_BACK _UxGT("Retour") -#define MSG_SD_INSERTED _UxGT("Carte insérée") -#define MSG_SD_REMOVED _UxGT("Carte retirée") -#define MSG_LCD_ENDSTOPS _UxGT("Butées") // Max length 8 characters +#define MSG_SD_INSERTED _UxGT("Carte inseree") +#define MSG_SD_REMOVED _UxGT("Carte retiree") +#define MSG_LCD_ENDSTOPS _UxGT("Butees") // Max length 8 characters #define MSG_MAIN _UxGT("Menu principal") #define MSG_AUTOSTART _UxGT("Demarrage auto") -#define MSG_DISABLE_STEPPERS _UxGT("Arrêter moteurs") +#define MSG_DISABLE_STEPPERS _UxGT("Arreter moteurs") #define MSG_DEBUG_MENU _UxGT("Menu debug") #define MSG_PROGRESS_BAR_TEST _UxGT("Test barre progress.") #define MSG_AUTO_HOME _UxGT("Origine auto.") @@ -50,57 +50,57 @@ #define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ") #define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer") #define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant") -#define MSG_LEVEL_BED_DONE _UxGT("Mise à niveau OK!") +#define MSG_LEVEL_BED_DONE _UxGT("Mise a niveau OK!") #define MSG_Z_FADE_HEIGHT _UxGT("Adoucir hauteur") -#define MSG_SET_HOME_OFFSETS _UxGT("Regl. décal. origine") -#define MSG_HOME_OFFSETS_APPLIED _UxGT("Décalages appliqués") -#define MSG_SET_ORIGIN _UxGT("Régler origine") -#define MSG_PREHEAT_1 _UxGT("Préchauffage PLA") -#define MSG_PREHEAT_1_N _UxGT("Préchauff. PLA ") -#define MSG_PREHEAT_1_ALL _UxGT("Préch. PLA Tout") +#define MSG_SET_HOME_OFFSETS _UxGT("Regl. decal. origine") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Decalages appliques") +#define MSG_SET_ORIGIN _UxGT("Regler origine") +#define MSG_PREHEAT_1 _UxGT("Prechauffage PLA") +#define MSG_PREHEAT_1_N _UxGT("Prechauff. PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Prech. PLA Tout") #define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini") -#define MSG_PREHEAT_1_BEDONLY _UxGT("Préch. PLA lit") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Prech. PLA lit") #define MSG_PREHEAT_1_SETTINGS _UxGT("Regl. prech. PLA") -#define MSG_PREHEAT_2 _UxGT("Préchauffage ABS") -#define MSG_PREHEAT_2_N _UxGT("Préchauff. ABS ") -#define MSG_PREHEAT_2_ALL _UxGT("Préch. ABS Tout") +#define MSG_PREHEAT_2 _UxGT("Prechauffage ABS") +#define MSG_PREHEAT_2_N _UxGT("Prechauff. ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Prech. ABS Tout") #define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini") -#define MSG_PREHEAT_2_BEDONLY _UxGT("Préch. ABS lit") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Prech. ABS lit") #define MSG_PREHEAT_2_SETTINGS _UxGT("Regl. prech. ABS") #define MSG_COOLDOWN _UxGT("Refroidir") #define MSG_SWITCH_PS_ON _UxGT("Allumer alim.") -#define MSG_SWITCH_PS_OFF _UxGT("Éteindre alim.") -#define MSG_EXTRUDE _UxGT("Éxtrusion") -#define MSG_RETRACT _UxGT("Rétraction") -#define MSG_MOVE_AXIS _UxGT("Déplacer un axe") -#define MSG_BED_LEVELING _UxGT("Règl. Niv. lit") -#define MSG_LEVEL_BED _UxGT("Règl. Niv. lit") -#define MSG_EDITING_STOPPED _UxGT("Arrêt edit. maillage") +#define MSG_SWITCH_PS_OFF _UxGT("eteindre alim.") +#define MSG_EXTRUDE _UxGT("extrusion") +#define MSG_RETRACT _UxGT("Retraction") +#define MSG_MOVE_AXIS _UxGT("Deplacer un axe") +#define MSG_BED_LEVELING _UxGT("Regl. Niv. lit") +#define MSG_LEVEL_BED _UxGT("Regl. Niv. lit") +#define MSG_EDITING_STOPPED _UxGT("Arret edit. maillage") #define MSG_USER_MENU _UxGT("Commandes perso") #define MSG_UBL_DOING_G29 _UxGT("G29 en cours") #define MSG_UBL_UNHOMED _UxGT("Origine XYZ d'abord") #define MSG_UBL_TOOLS _UxGT("Outils UBL") -#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié") +#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifie") #define MSG_UBL_MANUAL_MESH _UxGT("Maillage manuel") -#define MSG_UBL_BC_INSERT _UxGT("Poser câle & mesurer") +#define MSG_UBL_BC_INSERT _UxGT("Poser cale & mesurer") #define MSG_UBL_BC_INSERT2 _UxGT("Mesure") -#define MSG_UBL_BC_REMOVE _UxGT("ôter et mesurer lit") +#define MSG_UBL_BC_REMOVE _UxGT("oter et mesurer lit") #define MSG_UBL_MOVING_TO_NEXT _UxGT("Aller au suivant") #define MSG_UBL_ACTIVATE_MESH _UxGT("Activer l'UBL") -#define MSG_UBL_DEACTIVATE_MESH _UxGT("Désactiver l'UBL") -#define MSG_UBL_SET_BED_TEMP _UxGT("Température lit") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Desactiver l'UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Temperature lit") #define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP -#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Température buse") +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Temperature buse") #define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP #define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Editer maille perso") -#define MSG_UBL_FINE_TUNE_MESH _UxGT("Réglage fin maille") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Reglage fin maille") #define MSG_UBL_DONE_EDITING_MESH _UxGT("Termier maille") -#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Créer maille perso") -#define MSG_UBL_BUILD_MESH_MENU _UxGT("Créer maille") -#define MSG_UBL_BUILD_PLA_MESH _UxGT("Créer maille PLA") -#define MSG_UBL_BUILD_ABS_MESH _UxGT("Créer maille ABS") -#define MSG_UBL_BUILD_COLD_MESH _UxGT("Créer maille froide") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Creer maille perso") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Creer maille") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Creer maille PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Creer maille ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Creer maille froide") #define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Ajuster haut. maille") #define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Hauteur") #define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Valider maille") @@ -109,13 +109,13 @@ #define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Valider maille perso") #define MSG_UBL_CONTINUE_MESH _UxGT("Continuer maille") #define MSG_UBL_MESH_LEVELING _UxGT("Niveau par maille") -#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Niveau à 3 points") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Niveau a 3 points") #define MSG_UBL_GRID_MESH_LEVELING _UxGT("Niveau grille") #define MSG_UBL_MESH_LEVEL _UxGT("Maille de niveau") -#define MSG_UBL_SIDE_POINTS _UxGT("Point latéral") +#define MSG_UBL_SIDE_POINTS _UxGT("Point lateral") #define MSG_UBL_MAP_TYPE _UxGT("Type de carte") #define MSG_UBL_OUTPUT_MAP _UxGT("Voir maille") -#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Voir pour hôte") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Voir pour hote") #define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Voir pour CSV") #define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Off Printer Backup") #define MSG_UBL_INFO_UBL _UxGT("Voir info UBL") @@ -125,59 +125,59 @@ #define MSG_UBL_SMART_FILLIN _UxGT("Remplissage auto") #define MSG_UBL_FILLIN_MESH _UxGT("Maille remplissage") #define MSG_UBL_INVALIDATE_ALL _UxGT("Annuler tout") -#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Annuler le plus près") -#define MSG_UBL_FINE_TUNE_ALL _UxGT("Réglage fin (tous)") -#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Réglage fin (proche)") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Annuler le plus pres") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Reglage fin (tous)") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Reglage fin (proche)") #define MSG_UBL_STORAGE_MESH_MENU _UxGT("Stockage maille") -#define MSG_UBL_STORAGE_SLOT _UxGT("Slot mémoire") +#define MSG_UBL_STORAGE_SLOT _UxGT("Slot memoire") #define MSG_UBL_LOAD_MESH _UxGT("Charger maille") #define MSG_UBL_SAVE_MESH _UxGT("Sauver maille") #define MSG_UBL_SAVE_ERROR _UxGT("Err: Enreg. UBL") #define MSG_UBL_RESTORE_ERROR _UxGT("Err: Ouvrir UBL") -#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Offset Z arrêté") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Offset Z arrete") -#define MSG_MOVING _UxGT("Déplacement...") -#define MSG_FREE_XY _UxGT("Débloquer XY") -#define MSG_MOVE_X _UxGT("Dépl. X") -#define MSG_MOVE_Y _UxGT("Dépl. Y") -#define MSG_MOVE_Z _UxGT("Dépl. Z") +#define MSG_MOVING _UxGT("Deplacement...") +#define MSG_FREE_XY _UxGT("Debloquer XY") +#define MSG_MOVE_X _UxGT("Depl. X") +#define MSG_MOVE_Y _UxGT("Depl. Y") +#define MSG_MOVE_Z _UxGT("Depl. Z") #define MSG_MOVE_E _UxGT("Extruder") -#define MSG_MOVE_01MM _UxGT("Dépl. 0.1mm") -#define MSG_MOVE_1MM _UxGT("Dépl. 1mm") -#define MSG_MOVE_10MM _UxGT("Dépl. 10mm") +#define MSG_MOVE_01MM _UxGT("Depl. 0.1mm") +#define MSG_MOVE_1MM _UxGT("Depl. 1mm") +#define MSG_MOVE_10MM _UxGT("Depl. 10mm") #define MSG_SPEED _UxGT(" Vitesse") #define MSG_BED_Z _UxGT("Lit Z") #define MSG_NOZZLE _UxGT("Buse") #define MSG_BED _UxGT("Lit") #define MSG_FAN_SPEED _UxGT("Vitesse ventil.") #define MSG_FLOW _UxGT("Flux") -#define MSG_CONTROL _UxGT("Contrôler") +#define MSG_CONTROL _UxGT("Controler") #define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") #define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") #define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Facteur") #define MSG_AUTOTEMP _UxGT("Temp. Auto.") -#define MSG_ON _UxGT("Marche ") -#define MSG_OFF _UxGT("Arrêt") +#define MSG_ON _UxGT("Marche") +#define MSG_OFF _UxGT("Arret") #define MSG_PID_P _UxGT("PID-P") #define MSG_PID_I _UxGT("PID-I") #define MSG_PID_D _UxGT("PID-D") #define MSG_PID_C _UxGT("PID-C") -#define MSG_SELECT _UxGT("Sélectionner") -#define MSG_ACC _UxGT("Accélération") +#define MSG_SELECT _UxGT("Selectionner") +#define MSG_ACC _UxGT("Acceleration") #define MSG_JERK _UxGT("Jerk") #define MSG_VX_JERK _UxGT("Vx-jerk") #define MSG_VY_JERK _UxGT("Vy-jerk") #define MSG_VZ_JERK _UxGT("Vz-jerk") #define MSG_VE_JERK _UxGT("Ve-jerk") -#define MSG_VELOCITY _UxGT("Vélocité") +#define MSG_VELOCITY _UxGT("Velocite") #define MSG_VMAX _UxGT("Vmax") #define MSG_VMIN _UxGT("Vmin") #define MSG_VTRAV_MIN _UxGT("Vdepl min") -#define MSG_ACCELERATION _UxGT("Accélération") +#define MSG_ACCELERATION _UxGT("Acceleration") #define MSG_AMAX _UxGT("Amax ") #define MSG_A_RETRACT _UxGT("A-retract") -#define MSG_A_TRAVEL _UxGT("A-Dépl.") +#define MSG_A_TRAVEL _UxGT("A-Depl.") #define MSG_STEPS_PER_MM _UxGT("Pas/mm") #define MSG_XSTEPS _UxGT("Xpas/mm") #define MSG_YSTEPS _UxGT("Ypas/mm") @@ -188,7 +188,7 @@ #define MSG_E3STEPS _UxGT("E3pas/mm") #define MSG_E4STEPS _UxGT("E4pas/mm") #define MSG_E5STEPS _UxGT("E5pas/mm") -#define MSG_TEMPERATURE _UxGT("Température") +#define MSG_TEMPERATURE _UxGT("Temperature") #define MSG_MOTION _UxGT("Mouvement") #define MSG_FILAMENT _UxGT("Filament") #define MSG_VOLUMETRIC_ENABLED _UxGT("E en mm3") @@ -197,49 +197,50 @@ #define MSG_CONTRAST _UxGT("Contraste LCD") #define MSG_STORE_EEPROM _UxGT("Sauver config") #define MSG_LOAD_EEPROM _UxGT("Lire config") -#define MSG_RESTORE_FAILSAFE _UxGT("Restaurer défauts") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaurer defauts") #define MSG_INIT_EEPROM _UxGT("Initialiser EEPROM") #define MSG_REFRESH _UxGT("Actualiser") #define MSG_WATCH _UxGT("Surveiller") -#define MSG_PREPARE _UxGT("Préparer") -#define MSG_TUNE _UxGT("Régler") +#define MSG_PREPARE _UxGT("Preparer") +#define MSG_TUNE _UxGT("Regler") #define MSG_PAUSE_PRINT _UxGT("Interrompre impr.") #define MSG_RESUME_PRINT _UxGT("Reprendre impr.") -#define MSG_STOP_PRINT _UxGT("Arrêter impr.") +#define MSG_STOP_PRINT _UxGT("Arreter impr.") #define MSG_CARD_MENU _UxGT("Impr. depuis SD") #define MSG_NO_CARD _UxGT("Pas de carte") #define MSG_DWELL _UxGT("Repos...") #define MSG_USERWAIT _UxGT("Atten. de l'util.") #define MSG_PRINT_PAUSED _UxGT("Impr. en pause") #define MSG_RESUMING _UxGT("Repri. de l'impr.") -#define MSG_PRINT_ABORTED _UxGT("Impr. Annulée") -#define MSG_NO_MOVE _UxGT("Moteurs bloqués.") +#define MSG_PRINT_ABORTED _UxGT("Impr. Annulee") +#define MSG_NO_MOVE _UxGT("Moteurs bloques.") #define MSG_KILLED _UxGT("MORT.") -#define MSG_STOPPED _UxGT("STOPPÉ.") +#define MSG_STOPPED _UxGT("STOPPe.") #define MSG_CONTROL_RETRACT _UxGT("Retraction mm") #define MSG_CONTROL_RETRACT_SWAP _UxGT("Ech. Retr. mm") -#define MSG_CONTROL_RETRACTF _UxGT("Rétraction V") +#define MSG_CONTROL_RETRACTF _UxGT("Retraction V") #define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Saut Z mm") #define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") #define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Ech. UnRet mm") #define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") -#define MSG_AUTORETRACT _UxGT("Rétract. Auto.") +#define MSG_CONTROL_RETRACT_RECOVER_SWAPF _UxGT("Ech. UnRet V") +#define MSG_AUTORETRACT _UxGT("Retract. Auto.") #define MSG_FILAMENTCHANGE _UxGT("Changer filament") #define MSG_INIT_SDCARD _UxGT("Init. la carte SD") #define MSG_CNG_SDCARD _UxGT("Changer de carte") -#define MSG_ZPROBE_OUT _UxGT("Z sonde extè. lit") +#define MSG_ZPROBE_OUT _UxGT("Z sonde exte. lit") #define MSG_BLTOUCH _UxGT("BLTouch") #define MSG_BLTOUCH_SELFTEST _UxGT("Autotest BLTouch") #define MSG_BLTOUCH_RESET _UxGT("RaZ BLTouch") -#define MSG_BLTOUCH_DEPLOY _UxGT("Déployer BLTouch") +#define MSG_BLTOUCH_DEPLOY _UxGT("Deployer BLTouch") #define MSG_BLTOUCH_STOW _UxGT("Ranger BLTouch") #define MSG_HOME _UxGT("Origine") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST #define MSG_FIRST _UxGT("Premier") -#define MSG_ZPROBE_ZOFFSET _UxGT("Décalage Z") +#define MSG_ZPROBE_ZOFFSET _UxGT("Decalage Z") #define MSG_BABYSTEP_X _UxGT("Babystep X") #define MSG_BABYSTEP_Y _UxGT("Babystep Y") #define MSG_BABYSTEP_Z _UxGT("Babystep Z") -#define MSG_ENDSTOP_ABORT _UxGT("Butée abandon") +#define MSG_ENDSTOP_ABORT _UxGT("Butee abandon") #define MSG_HEATING_FAILED_LCD _UxGT("Erreur de chauffe") #define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: TEMP. REDONDANT") #define MSG_THERMAL_RUNAWAY _UxGT("EMBALLEMENT THERM.") @@ -249,16 +250,16 @@ #define MSG_ERR_MINTEMP_BED _UxGT("Err: TEMP. MIN LIT") #define MSG_ERR_Z_HOMING _UxGT("G28 Z interdit") -#define MSG_HALTED _UxGT("IMPR. STOPPÉE") +#define MSG_HALTED _UxGT("IMPR. STOPPeE") #define MSG_PLEASE_RESET _UxGT("RaZ. SVP") #define MSG_SHORT_DAY _UxGT("j") // One character only #define MSG_SHORT_HOUR _UxGT("h") // One character only #define MSG_SHORT_MINUTE _UxGT("m") // One character only #define MSG_HEATING _UxGT("En chauffe...") -#define MSG_HEATING_COMPLETE _UxGT("Chauffe terminée") +#define MSG_HEATING_COMPLETE _UxGT("Chauffe terminee") #define MSG_BED_HEATING _UxGT("Lit en chauffe..") -#define MSG_BED_DONE _UxGT("Chauffe lit terminée") +#define MSG_BED_DONE _UxGT("Chauffe lit terminee") #define MSG_DELTA_CALIBRATE _UxGT("Calibration Delta") #define MSG_DELTA_CALIBRATE_X _UxGT("Calibrer X") #define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrer Y") @@ -269,10 +270,10 @@ #define MSG_INFO_MENU _UxGT("Infos imprimante") #define MSG_INFO_PRINTER_MENU _UxGT("Infos imprimante") -#define MSG_3POINT_LEVELING _UxGT("Niveau à 3 points") -#define MSG_LINEAR_LEVELING _UxGT("Niveau linéaire") -#define MSG_BILINEAR_LEVELING _UxGT("Niveau bilinéaire") -#define MSG_UBL_LEVELING _UxGT("Niveau lit unifié") +#define MSG_3POINT_LEVELING _UxGT("Niveau a 3 points") +#define MSG_LINEAR_LEVELING _UxGT("Niveau lineaire") +#define MSG_BILINEAR_LEVELING _UxGT("Niveau bilineaire") +#define MSG_UBL_LEVELING _UxGT("Niveau lit unifie") #define MSG_MESH_LEVELING _UxGT("Niveau maillage") #define MSG_INFO_STATS_MENU _UxGT("Stats. imprimante") #define MSG_INFO_BOARD_MENU _UxGT("Infos carte") @@ -280,18 +281,18 @@ #define MSG_INFO_EXTRUDERS _UxGT("Extrudeurs") #define MSG_INFO_BAUDRATE _UxGT("Baud") #define MSG_INFO_PROTOCOL _UxGT("Protocole") -#define MSG_CASE_LIGHT _UxGT("Lumière caisson") -#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Luminosité") +#define MSG_CASE_LIGHT _UxGT("Lumiere caisson") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Luminosite") #if LCD_WIDTH >= 20 #define MSG_INFO_PRINT_COUNT _UxGT("Nbre impressions") - #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminees") #define MSG_INFO_PRINT_TIME _UxGT("Tps impr. total") #define MSG_INFO_PRINT_LONGEST _UxGT("Impr. la + longue") #define MSG_INFO_PRINT_FILAMENT _UxGT("Total filament") #else #define MSG_INFO_PRINT_COUNT _UxGT("Impressions") - #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminees") #define MSG_INFO_PRINT_TIME _UxGT("Total") #define MSG_INFO_PRINT_LONGEST _UxGT("+ long") #define MSG_INFO_PRINT_FILAMENT _UxGT("Filament") @@ -313,12 +314,12 @@ #if LCD_HEIGHT >= 4 // Up to 3 lines allowed - #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attente Démarrage") + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attente Demarrage") #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("du filament") #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("changer") #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("attente de") - #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("décharger filament") - #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("insérer filament") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("decharger filament") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("inserer filament") #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("et app. bouton") #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("pour continuer...") #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Presser le bouton...") @@ -335,7 +336,7 @@ // Up to 2 lines allowed #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Patientez...") #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejection...") - #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insérer et clic") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserer et clic") #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Chargement...") #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrusion...") #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Reprise...") diff --git a/Marlin/language_fr_utf8.h b/Marlin/language_fr_utf8.h new file mode 100644 index 0000000000..ab328950f0 --- /dev/null +++ b/Marlin/language_fr_utf8.h @@ -0,0 +1,344 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * French + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_FR_UTF_H +#define LANGUAGE_FR_UTF_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" prête.") +#define MSG_BACK _UxGT("Retour") +#define MSG_SD_INSERTED _UxGT("Carte insérée") +#define MSG_SD_REMOVED _UxGT("Carte retirée") +#define MSG_LCD_ENDSTOPS _UxGT("Butées") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Demarrage auto") +#define MSG_DISABLE_STEPPERS _UxGT("Arrêter moteurs") +#define MSG_DEBUG_MENU _UxGT("Menu debug") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test barre progress.") +#define MSG_AUTO_HOME _UxGT("Origine auto.") +#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.") +#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.") +#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.") +#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant") +#define MSG_LEVEL_BED_DONE _UxGT("Mise à niveau OK!") +#define MSG_Z_FADE_HEIGHT _UxGT("Adoucir hauteur") +#define MSG_SET_HOME_OFFSETS _UxGT("Regl. décal. origine") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Décalages appliqués") +#define MSG_SET_ORIGIN _UxGT("Régler origine") +#define MSG_PREHEAT_1 _UxGT("Préchauffage PLA") +#define MSG_PREHEAT_1_N _UxGT("Préchauff. PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Préch. PLA Tout") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Préch. PLA lit") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Regl. prech. PLA") +#define MSG_PREHEAT_2 _UxGT("Préchauffage ABS") +#define MSG_PREHEAT_2_N _UxGT("Préchauff. ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Préch. ABS Tout") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Préch. ABS lit") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Regl. prech. ABS") +#define MSG_COOLDOWN _UxGT("Refroidir") +#define MSG_SWITCH_PS_ON _UxGT("Allumer alim.") +#define MSG_SWITCH_PS_OFF _UxGT("Éteindre alim.") +#define MSG_EXTRUDE _UxGT("Éxtrusion") +#define MSG_RETRACT _UxGT("Rétraction") +#define MSG_MOVE_AXIS _UxGT("Déplacer un axe") +#define MSG_BED_LEVELING _UxGT("Règl. Niv. lit") +#define MSG_LEVEL_BED _UxGT("Règl. Niv. lit") +#define MSG_EDITING_STOPPED _UxGT("Arrêt edit. maillage") +#define MSG_USER_MENU _UxGT("Commandes perso") + +#define MSG_UBL_DOING_G29 _UxGT("G29 en cours") +#define MSG_UBL_UNHOMED _UxGT("Origine XYZ d'abord") +#define MSG_UBL_TOOLS _UxGT("Outils UBL") +#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié") +#define MSG_UBL_MANUAL_MESH _UxGT("Maillage manuel") +#define MSG_UBL_BC_INSERT _UxGT("Poser câle & mesurer") +#define MSG_UBL_BC_INSERT2 _UxGT("Mesure") +#define MSG_UBL_BC_REMOVE _UxGT("ôter et mesurer lit") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Aller au suivant") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Activer l'UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Désactiver l'UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Température lit") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Température buse") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Editer maille perso") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Réglage fin maille") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Termier maille") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Créer maille perso") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Créer maille") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Créer maille PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Créer maille ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Créer maille froide") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Ajuster haut. maille") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Hauteur") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Valider maille") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Valider maille PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Valider maille ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Valider maille perso") +#define MSG_UBL_CONTINUE_MESH _UxGT("Continuer maille") +#define MSG_UBL_MESH_LEVELING _UxGT("Niveau par maille") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Niveau à 3 points") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Niveau grille") +#define MSG_UBL_MESH_LEVEL _UxGT("Maille de niveau") +#define MSG_UBL_SIDE_POINTS _UxGT("Point latéral") +#define MSG_UBL_MAP_TYPE _UxGT("Type de carte") +#define MSG_UBL_OUTPUT_MAP _UxGT("Voir maille") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Voir pour hôte") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Voir pour CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Off Printer Backup") +#define MSG_UBL_INFO_UBL _UxGT("Voir info UBL") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Modifier maille") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Taux de remplissage") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Remplissage manuel") +#define MSG_UBL_SMART_FILLIN _UxGT("Remplissage auto") +#define MSG_UBL_FILLIN_MESH _UxGT("Maille remplissage") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Annuler tout") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Annuler le plus près") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Réglage fin (tous)") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Réglage fin (proche)") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Stockage maille") +#define MSG_UBL_STORAGE_SLOT _UxGT("Slot mémoire") +#define MSG_UBL_LOAD_MESH _UxGT("Charger maille") +#define MSG_UBL_SAVE_MESH _UxGT("Sauver maille") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Enreg. UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Ouvrir UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Offset Z arrêté") + + +#define MSG_MOVING _UxGT("Déplacement...") +#define MSG_FREE_XY _UxGT("Débloquer XY") +#define MSG_MOVE_X _UxGT("Dépl. X") +#define MSG_MOVE_Y _UxGT("Dépl. Y") +#define MSG_MOVE_Z _UxGT("Dépl. Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Dépl. 0.1mm") +#define MSG_MOVE_1MM _UxGT("Dépl. 1mm") +#define MSG_MOVE_10MM _UxGT("Dépl. 10mm") +#define MSG_SPEED _UxGT(" Vitesse") +#define MSG_BED_Z _UxGT("Lit Z") +#define MSG_NOZZLE _UxGT("Buse") +#define MSG_BED _UxGT("Lit") +#define MSG_FAN_SPEED _UxGT("Vitesse ventil.") +#define MSG_FLOW _UxGT("Flux") +#define MSG_CONTROL _UxGT("Contrôler") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Facteur") +#define MSG_AUTOTEMP _UxGT("Temp. Auto.") +#define MSG_ON _UxGT("Marche ") +#define MSG_OFF _UxGT("Arrêt") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Sélectionner") +#define MSG_ACC _UxGT("Accélération") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VELOCITY _UxGT("Vélocité") +#define MSG_VMAX _UxGT("Vmax") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vdepl min") +#define MSG_ACCELERATION _UxGT("Accélération") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-Dépl.") +#define MSG_STEPS_PER_MM _UxGT("Pas/mm") +#define MSG_XSTEPS _UxGT("Xpas/mm") +#define MSG_YSTEPS _UxGT("Ypas/mm") +#define MSG_ZSTEPS _UxGT("Zpas/mm") +#define MSG_ESTEPS _UxGT("Epas/mm") +#define MSG_E1STEPS _UxGT("E1pas/mm") +#define MSG_E2STEPS _UxGT("E2pas/mm") +#define MSG_E3STEPS _UxGT("E3pas/mm") +#define MSG_E4STEPS _UxGT("E4pas/mm") +#define MSG_E5STEPS _UxGT("E5pas/mm") +#define MSG_TEMPERATURE _UxGT("Température") +#define MSG_MOTION _UxGT("Mouvement") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E en mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diam. Fil.") +#define MSG_ADVANCE_K _UxGT("Advance K") +#define MSG_CONTRAST _UxGT("Contraste LCD") +#define MSG_STORE_EEPROM _UxGT("Sauver config") +#define MSG_LOAD_EEPROM _UxGT("Lire config") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaurer défauts") +#define MSG_INIT_EEPROM _UxGT("Initialiser EEPROM") +#define MSG_REFRESH _UxGT("Actualiser") +#define MSG_WATCH _UxGT("Surveiller") +#define MSG_PREPARE _UxGT("Préparer") +#define MSG_TUNE _UxGT("Régler") +#define MSG_PAUSE_PRINT _UxGT("Interrompre impr.") +#define MSG_RESUME_PRINT _UxGT("Reprendre impr.") +#define MSG_STOP_PRINT _UxGT("Arrêter impr.") +#define MSG_CARD_MENU _UxGT("Impr. depuis SD") +#define MSG_NO_CARD _UxGT("Pas de carte") +#define MSG_DWELL _UxGT("Repos...") +#define MSG_USERWAIT _UxGT("Atten. de l'util.") +#define MSG_PRINT_PAUSED _UxGT("Impr. en pause") +#define MSG_RESUMING _UxGT("Repri. de l'impr.") +#define MSG_PRINT_ABORTED _UxGT("Impr. Annulée") +#define MSG_NO_MOVE _UxGT("Moteurs bloqués.") +#define MSG_KILLED _UxGT("MORT.") +#define MSG_STOPPED _UxGT("STOPPÉ.") +#define MSG_CONTROL_RETRACT _UxGT("Retraction mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Ech. Retr. mm") +#define MSG_CONTROL_RETRACTF _UxGT("Rétraction V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Saut Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Ech. UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("Rétract. Auto.") +#define MSG_FILAMENTCHANGE _UxGT("Changer filament") +#define MSG_INIT_SDCARD _UxGT("Init. la carte SD") +#define MSG_CNG_SDCARD _UxGT("Changer de carte") +#define MSG_ZPROBE_OUT _UxGT("Z sonde extè. lit") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Autotest BLTouch") +#define MSG_BLTOUCH_RESET _UxGT("RaZ BLTouch") +#define MSG_BLTOUCH_DEPLOY _UxGT("Déployer BLTouch") +#define MSG_BLTOUCH_STOW _UxGT("Ranger BLTouch") +#define MSG_HOME _UxGT("Origine") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("Premier") +#define MSG_ZPROBE_ZOFFSET _UxGT("Décalage Z") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Butée abandon") +#define MSG_HEATING_FAILED_LCD _UxGT("Erreur de chauffe") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: TEMP. REDONDANT") +#define MSG_THERMAL_RUNAWAY _UxGT("EMBALLEMENT THERM.") +#define MSG_ERR_MAXTEMP _UxGT("Err: TEMP. MAX") +#define MSG_ERR_MINTEMP _UxGT("Err: TEMP. MIN") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: TEMP. MAX LIT") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: TEMP. MIN LIT") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z interdit") + +#define MSG_HALTED _UxGT("IMPR. STOPPÉE") +#define MSG_PLEASE_RESET _UxGT("RaZ. SVP") +#define MSG_SHORT_DAY _UxGT("j") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only + +#define MSG_HEATING _UxGT("En chauffe...") +#define MSG_HEATING_COMPLETE _UxGT("Chauffe terminée") +#define MSG_BED_HEATING _UxGT("Lit en chauffe..") +#define MSG_BED_DONE _UxGT("Chauffe lit terminée") +#define MSG_DELTA_CALIBRATE _UxGT("Calibration Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrer X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrer Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrer Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrer centre") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Calibration Auto") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Hauteur Delta") + +#define MSG_INFO_MENU _UxGT("Infos imprimante") +#define MSG_INFO_PRINTER_MENU _UxGT("Infos imprimante") +#define MSG_3POINT_LEVELING _UxGT("Niveau à 3 points") +#define MSG_LINEAR_LEVELING _UxGT("Niveau linéaire") +#define MSG_BILINEAR_LEVELING _UxGT("Niveau bilinéaire") +#define MSG_UBL_LEVELING _UxGT("Niveau lit unifié") +#define MSG_MESH_LEVELING _UxGT("Niveau maillage") +#define MSG_INFO_STATS_MENU _UxGT("Stats. imprimante") +#define MSG_INFO_BOARD_MENU _UxGT("Infos carte") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extrudeurs") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocole") +#define MSG_CASE_LIGHT _UxGT("Lumière caisson") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Luminosité") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Nbre impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_PRINT_TIME _UxGT("Tps impr. total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Impr. la + longue") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total filament") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("+ long") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Filament") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Temp Min") +#define MSG_INFO_MAX_TEMP _UxGT("Temp Max") +#define MSG_INFO_PSU _UxGT("Alimentation") +#define MSG_DRIVE_STRENGTH _UxGT("Puiss. moteur ") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM sauv.") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("+ extrusion") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Reprendre impr.") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("La temp. minimum est ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Buse: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attente Démarrage") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("du filament") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("changer") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("décharger filament") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("insérer filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("et app. bouton") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("pour continuer...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Presser le bouton...") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Pr chauffer la buse") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Buse en chauffe") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Patientez SVP...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("chargement filament") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extrusion filament") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("attente impression") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("pour reprendre") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Patientez...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejection...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insérer et clic") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Chargement...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrusion...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Reprise...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_FR_UTF_H diff --git a/Marlin/language_gl.h b/Marlin/language_gl.h index 4797297f01..f8d50035e7 100644 --- a/Marlin/language_gl.h +++ b/Marlin/language_gl.h @@ -32,6 +32,7 @@ #define MAPPER_C2C3 #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME _UxGT(" lista.") #define MSG_SD_INSERTED _UxGT("Tarxeta inserida") diff --git a/Marlin/language_nl.h b/Marlin/language_nl.h index 7a60501877..11f612de81 100644 --- a/Marlin/language_nl.h +++ b/Marlin/language_nl.h @@ -31,6 +31,7 @@ #define LANGUAGE_NL_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME _UxGT(" gereed.") #define MSG_BACK _UxGT("Terug") diff --git a/Marlin/language_pl-DOGM.h b/Marlin/language_pl-DOGM.h index d93cfa454b..e712185c61 100644 --- a/Marlin/language_pl-DOGM.h +++ b/Marlin/language_pl-DOGM.h @@ -24,6 +24,9 @@ * Polish for DOGM display - includes accented characters */ +#ifndef LANGUAGE_PL_DOGM_H +#define LANGUAGE_PL_DOGM_H + #define WELCOME_MSG MACHINE_NAME _UxGT(" gotowy.") #define MSG_SD_INSERTED _UxGT("Karta włożona") #define MSG_SD_REMOVED _UxGT("Karta usunięta") @@ -40,6 +43,7 @@ #define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.") #define MSG_LEVEL_BED_NEXT_POINT _UxGT("Następny punkt") #define MSG_LEVEL_BED_DONE _UxGT("Wypoziomowano!") +#define MSG_USER_MENU _UxGT("Własne Polecenia") #define MSG_SET_HOME_OFFSETS _UxGT("Ust. poz. zer.") #define MSG_HOME_OFFSETS_APPLIED _UxGT("Poz. zerowa ust.") #define MSG_SET_ORIGIN _UxGT("Ustaw punkt zero") @@ -238,3 +242,5 @@ #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Ekstruzja...") #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wznowienie...") #endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_PL_DOGM_H diff --git a/Marlin/language_pl-HD44780.h b/Marlin/language_pl-HD44780.h index 7c5ea08380..d14cf9d77a 100644 --- a/Marlin/language_pl-HD44780.h +++ b/Marlin/language_pl-HD44780.h @@ -24,6 +24,11 @@ * Polish for HD44780 display - no accented characters */ +#ifndef LANGUAGE_PL_HD44780_H +#define LANGUAGE_PL_HD44780_H + +#define NOT_EXTENDED_ISO10646_1_5X7 + #define WELCOME_MSG MACHINE_NAME _UxGT(" gotowy.") #define MSG_SD_INSERTED _UxGT("Karta wlozona") #define MSG_SD_REMOVED _UxGT("Karta usunieta") @@ -40,6 +45,7 @@ #define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.") #define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nastepny punkt") #define MSG_LEVEL_BED_DONE _UxGT("Wypoziomowano!") +#define MSG_USER_MENU _UxGT("Wlasne Polecenia") #define MSG_SET_HOME_OFFSETS _UxGT("Ust. poz. zer.") #define MSG_HOME_OFFSETS_APPLIED _UxGT("Poz. zerowa ust.") #define MSG_SET_ORIGIN _UxGT("Ustaw punkt zero") @@ -263,3 +269,5 @@ #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Ekstruzja...") #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wznowienie...") #endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_PL_HD44780_H diff --git a/Marlin/language_pt-br.h b/Marlin/language_pt-br.h index fa92224f3f..5ba2956023 100644 --- a/Marlin/language_pt-br.h +++ b/Marlin/language_pt-br.h @@ -31,6 +31,7 @@ #define LANGUAGE_PT_BR_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "Cartao inserido" diff --git a/Marlin/language_pt.h b/Marlin/language_pt.h index 06c4684890..9896005b9f 100644 --- a/Marlin/language_pt.h +++ b/Marlin/language_pt.h @@ -31,6 +31,7 @@ #define LANGUAGE_PT_H #define DISPLAY_CHARSET_ISO10646_1 +#define NOT_EXTENDED_ISO10646_1_5X7 #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "Cartao inserido" diff --git a/Marlin/language_zh_TW.h b/Marlin/language_zh_TW.h index 777c09312f..315f77f7f4 100644 --- a/Marlin/language_zh_TW.h +++ b/Marlin/language_zh_TW.h @@ -36,12 +36,12 @@ #define MSG_LCD_ENDSTOPS _UxGT("擋塊") //"Endstops" // Max length 8 characters #define MSG_MAIN _UxGT("主選單") //"Main" #define MSG_AUTOSTART _UxGT("自動開始") //"Autostart" -#define MSG_DISABLE_STEPPERS _UxGT("關閉步進驅動") //"Disable steppers" +#define MSG_DISABLE_STEPPERS _UxGT("關閉步進馬達") //"Disable steppers" #define MSG_AUTO_HOME _UxGT("自動回原點") //"Auto home" -#define MSG_AUTO_HOME_X _UxGT("回X原位") //"Home X" -#define MSG_AUTO_HOME_Y _UxGT("回Y原位") //"Home Y" -#define MSG_AUTO_HOME_Z _UxGT("回Z原位") //"Home Z" -#define MSG_LEVEL_BED_HOMING _UxGT("平台調平XYZ歸原位") //"Homing XYZ" +#define MSG_AUTO_HOME_X _UxGT("回X原點") //"Home X" +#define MSG_AUTO_HOME_Y _UxGT("回Y原點") //"Home Y" +#define MSG_AUTO_HOME_Z _UxGT("回Z原點") //"Home Z" +#define MSG_LEVEL_BED_HOMING _UxGT("平台調平XYZ歸原點") //"Homing XYZ" #define MSG_LEVEL_BED_WAITING _UxGT("單擊開始熱床調平") //"Click to Begin" #define MSG_LEVEL_BED_NEXT_POINT _UxGT("下個熱床調平點") //"Next Point" #define MSG_LEVEL_BED_DONE _UxGT("完成熱床調平") //"Leveling Done!" @@ -62,7 +62,7 @@ #define MSG_SWITCH_PS_ON _UxGT("電源打開") //"Switch power on" #define MSG_SWITCH_PS_OFF _UxGT("電源關閉") //"Switch power off" #define MSG_EXTRUDE _UxGT("擠出") //"Extrude" -#define MSG_RETRACT _UxGT("回抽") //"Retract" +#define MSG_RETRACT _UxGT("回縮") //"Retract" #define MSG_MOVE_AXIS _UxGT("移動軸") //"Move axis" #define MSG_BED_LEVELING _UxGT("調平熱床") //"Bed leveling" #define MSG_LEVEL_BED _UxGT("調平熱床") //"Level bed" @@ -101,7 +101,7 @@ #define MSG_VMIN _UxGT("最小進料速率") //"Vmin" min_feedrate_mm_s #define MSG_VTRAV_MIN _UxGT("最小移動速率") //"VTrav min" min_travel_feedrate_mm_s, (target) speed of the move #define MSG_AMAX _UxGT("最大列印加速度") //"Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves -#define MSG_A_RETRACT _UxGT("收進加速度") //"A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts +#define MSG_A_RETRACT _UxGT("回縮加速度") //"A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts #define MSG_A_TRAVEL _UxGT("非列印移動加速度") //"A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves #define MSG_STEPS_PER_MM _UxGT("軸步數/mm") //"Steps/mm" axis_steps_per_mm, axis steps-per-unit G92 #define MSG_XSTEPS _UxGT("X軸步數/mm") //"Xsteps/mm" axis_steps_per_mm, axis steps-per-unit G92 @@ -109,38 +109,38 @@ #define MSG_ZSTEPS _UxGT("Z軸步數/mm") //"Zsteps/mm" #define MSG_ESTEPS _UxGT("擠出機步數/mm") //"Esteps/mm" #define MSG_TEMPERATURE _UxGT("溫度") //"Temperature" -#define MSG_MOTION _UxGT("運動") //"Motion" +#define MSG_MOTION _UxGT("運作") //"Motion" #define MSG_FILAMENT _UxGT("絲料測容") //"Filament" lcd_control_volumetric_menu #define MSG_VOLUMETRIC_ENABLED _UxGT("測容積mm³") //"E in mm3" volumetric_enabled #define MSG_FILAMENT_DIAM _UxGT("絲料直徑") //"Fil. Dia." #define MSG_CONTRAST _UxGT("LCD對比度") //"LCD contrast" #define MSG_STORE_EEPROM _UxGT("保存設置") //"Store memory" -#define MSG_LOAD_EEPROM _UxGT("裝載設置") //"Load memory" -#define MSG_RESTORE_FAILSAFE _UxGT("恢複安全值") //"Restore failsafe" +#define MSG_LOAD_EEPROM _UxGT("載入設置") //"Load memory" +#define MSG_RESTORE_FAILSAFE _UxGT("恢復安全值") //"Restore failsafe" #define MSG_REFRESH _UxGT("刷新") //"Refresh" #define MSG_WATCH _UxGT("資訊界面") //"Info screen" #define MSG_PREPARE _UxGT("準備") //"Prepare" #define MSG_TUNE _UxGT("調整") //"Tune" #define MSG_PAUSE_PRINT _UxGT("暫停列印") //"Pause print" -#define MSG_RESUME_PRINT _UxGT("恢複列印") //"Resume print" +#define MSG_RESUME_PRINT _UxGT("恢復列印") //"Resume print" #define MSG_STOP_PRINT _UxGT("停止列印") //"Stop print" #define MSG_CARD_MENU _UxGT("從記憶卡上列印") //"Print from SD" #define MSG_NO_CARD _UxGT("無記憶卡") //"No SD card" #define MSG_DWELL _UxGT("休眠 ...") //"Sleep..." #define MSG_USERWAIT _UxGT("等待用戶 ...") //"Wait for user..." -#define MSG_RESUMING _UxGT("恢複列印中") //"Resuming print" +#define MSG_RESUMING _UxGT("恢復列印中") //"Resuming print" #define MSG_PRINT_ABORTED _UxGT("列印已取消") //"Print aborted" #define MSG_NO_MOVE _UxGT("無移動") //"No move." -#define MSG_KILLED _UxGT("已殺掉") //"KILLED. " +#define MSG_KILLED _UxGT("已砍掉") //"KILLED. " #define MSG_STOPPED _UxGT("已停止") //"STOPPED. " -#define MSG_CONTROL_RETRACT _UxGT("回抽長度mm") //"Retract mm" retract_length, retract length (positive mm) +#define MSG_CONTROL_RETRACT _UxGT("回縮長度mm") //"Retract mm" retract_length, retract length (positive mm) #define MSG_CONTROL_RETRACT_SWAP _UxGT("換手回抽長度mm") //"Swap Re.mm" swap_retract_length, swap retract length (positive mm), for extruder change -#define MSG_CONTROL_RETRACTF _UxGT("回抽速率mm/s") //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) +#define MSG_CONTROL_RETRACTF _UxGT("回縮速率mm/s") //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) #define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") //"Hop mm" retract_zlift, retract Z-lift -#define MSG_CONTROL_RETRACT_RECOVER _UxGT("回抽恢複長度mm") //"UnRet +mm" retract_recover_length, additional recover length (mm, added to retract length when recovering) -#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("換手回抽恢複長度mm") //"S UnRet+mm" swap_retract_recover_length, additional swap recover length (mm, added to retract length when recovering from extruder change) -#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("回抽恢複後進料速率mm/s") //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) -#define MSG_AUTORETRACT _UxGT("自動抽回") //"AutoRetr." autoretract_enabled, +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("回縮恢復長度mm") //"UnRet +mm" retract_recover_length, additional recover length (mm, added to retract length when recovering) +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("換手回縮恢復長度mm") //"S UnRet+mm" swap_retract_recover_length, additional swap recover length (mm, added to retract length when recovering from extruder change) +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("回縮恢復後進料速率mm/s") //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) +#define MSG_AUTORETRACT _UxGT("自動回縮") //"AutoRetr." autoretract_enabled, #define MSG_FILAMENTCHANGE _UxGT("更換絲料") //"Change filament" #define MSG_INIT_SDCARD _UxGT("初始化記憶卡") //"Init. SD card" #define MSG_CNG_SDCARD _UxGT("更換記憶卡") //"Change SD card" @@ -175,17 +175,17 @@ #define MSG_DELTA_CALIBRATE_CENTER _UxGT("校準中心") //"Calibrate Center" #define MSG_INFO_MENU _UxGT("關於印表機") //"About Printer" -#define MSG_INFO_PRINTER_MENU _UxGT("印表機信息") //"Printer Info" +#define MSG_INFO_PRINTER_MENU _UxGT("印表機訊息") //"Printer Info" #define MSG_INFO_STATS_MENU _UxGT("印表機統計") //"Printer Stats" -#define MSG_INFO_BOARD_MENU _UxGT("主板信息") //"Board Info" +#define MSG_INFO_BOARD_MENU _UxGT("主板訊息") //"Board Info" #define MSG_INFO_THERMISTOR_MENU _UxGT("溫度計") //"Thermistors" #define MSG_INFO_EXTRUDERS _UxGT("擠出機") //"Extruders" -#define MSG_INFO_BAUDRATE _UxGT("波特率") //"Baud" +#define MSG_INFO_BAUDRATE _UxGT("傳輸率") //"Baud" #define MSG_INFO_PROTOCOL _UxGT("協議") //"Protocol" #if LCD_WIDTH > 19 #define MSG_INFO_PRINT_COUNT _UxGT("列印計數") //"Print Count" -#define MSG_INFO_COMPLETED_PRINTS _UxGT("完成了") //"Completed" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("已完成") //"Completed" #define MSG_INFO_PRINT_TIME _UxGT("總列印時間") //"Total print time" #define MSG_INFO_PRINT_LONGEST _UxGT("最長工作時間") //"Longest job time" #define MSG_INFO_PRINT_FILAMENT _UxGT("總計擠出") //"Extruded total" @@ -204,7 +204,7 @@ #define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") #define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") #define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("擠出更多") //"Extrude more" -#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("恢複列印") //"Resume print" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("恢復列印") //"Resume print" #if LCD_HEIGHT >= 4 #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("等待開始") //"Wait for start" @@ -215,7 +215,7 @@ #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("") //"" #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入絲料") //"Insert filament" #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("並按鍵") //"and press button" -#define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("來繼續 ...") //"to continue..." +#define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("繼續 ...") //"to continue..." #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("等待") //"Wait for" #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("進料") //"filament load" #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("") //"" @@ -223,16 +223,16 @@ #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("絲料擠出") //"filament extrude" #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("") //"" #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("等待列印") //"Wait for print" -#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("恢複") //"to resume" +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("恢復") //"to resume" #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("") //"" #else // LCD_HEIGHT < 4 #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("請等待 ...") //"Please wait..." #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("退出中 ...") //"Ejecting..." -#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入並單擊") //"Insert and Click" -#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("裝載中 ...") //"Loading..." +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入並點擊") //"Insert and Click" +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("載入中 ...") //"Loading..." #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("擠出中 ...") //"Extruding..." -#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("恢複中 ...") //"Resuming..." +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("恢復中 ...") //"Resuming..." #endif // LCD_HEIGHT < 4 #endif // LANGUAGE_ZH_TW_H diff --git a/Marlin/leds.cpp b/Marlin/leds.cpp new file mode 100644 index 0000000000..df798acf8f --- /dev/null +++ b/Marlin/leds.cpp @@ -0,0 +1,140 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * leds.cpp - Marlin RGB LED general support + */ + +#include "MarlinConfig.h" + +#if HAS_COLOR_LEDS + +#include "leds.h" + +#if ENABLED(BLINKM) + #include "blinkm.h" +#endif + +#if ENABLED(PCA9632) + #include "pca9632.h" +#endif + +#if ENABLED(LED_COLOR_PRESETS) + const LEDColor LEDLights::defaultLEDColor = MakeLEDColor( + LED_USER_PRESET_RED, + LED_USER_PRESET_GREEN, + LED_USER_PRESET_BLUE, + LED_USER_PRESET_WHITE, + LED_USER_PRESET_BRIGHTNESS + ); +#endif + +#if ENABLED(LED_CONTROL_MENU) + LEDColor LEDLights::color; + bool LEDLights::lights_on; +#endif + +LEDLights leds; + +void LEDLights::setup() { + #if ENABLED(NEOPIXEL_LED) + setup_neopixel(); + #endif + #if ENABLED(LED_USER_PRESET_STARTUP) + set_default(); + #endif +} + +void LEDLights::set_color(const LEDColor &incol + #if ENABLED(NEOPIXEL_LED) + , bool isSequence/*=false*/ + #endif +) { + + #if ENABLED(NEOPIXEL_LED) + + const uint32_t neocolor = pixels.Color(incol.r, incol.g, incol.b, incol.w); + static uint16_t nextLed = 0; + + pixels.setBrightness(incol.i); + if (!isSequence) + set_neopixel_color(neocolor); + else { + pixels.setPixelColor(nextLed, neocolor); + pixels.show(); + if (++nextLed >= pixels.numPixels()) nextLed = 0; + return; + } + + #endif + + #if ENABLED(BLINKM) + + // This variant uses i2c to send the RGB components to the device. + blinkm_set_led_color(incol); + + #endif + + #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + + // This variant uses 3-4 separate pins for the RGB(W) components. + // If the pins can do PWM then their intensity will be set. + WRITE(RGB_LED_R_PIN, incol.r ? HIGH : LOW); + WRITE(RGB_LED_G_PIN, incol.g ? HIGH : LOW); + WRITE(RGB_LED_B_PIN, incol.b ? HIGH : LOW); + analogWrite(RGB_LED_R_PIN, incol.r); + analogWrite(RGB_LED_G_PIN, incol.g); + analogWrite(RGB_LED_B_PIN, incol.b); + + #if ENABLED(RGBW_LED) + WRITE(RGB_LED_W_PIN, incol.w ? HIGH : LOW); + analogWrite(RGB_LED_W_PIN, incol.w); + #endif + + #endif + + #if ENABLED(PCA9632) + // Update I2C LED driver + pca9632_set_led_color(incol); + #endif + + #if ENABLED(LED_CONTROL_MENU) + // Don't update the color when OFF + lights_on = !incol.is_off(); + if (lights_on) color = incol; + #endif +} + +void LEDLights::set_white() { + #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(BLINKM) || ENABLED(PCA9632) + set_color(LEDColorWhite()); + #endif + #if ENABLED(NEOPIXEL_LED) + set_neopixel_color(pixels.Color(NEO_WHITE)); + #endif +} + +#if ENABLED(LED_CONTROL_MENU) + void LEDLights::toggle() { if (lights_on) set_off(); else update(); } +#endif + +#endif // HAS_COLOR_LEDS diff --git a/Marlin/leds.h b/Marlin/leds.h new file mode 100644 index 0000000000..a0cf28b847 --- /dev/null +++ b/Marlin/leds.h @@ -0,0 +1,169 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * leds.h - Marlin general RGB LED support + */ + +#ifndef __LEDS_H__ +#define __LEDS_H__ + +#include "MarlinConfig.h" + +#if ENABLED(NEOPIXEL_LED) + #include "neopixel.h" +#endif + +#define HAS_WHITE_LED (ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED)) + +/** + * LEDcolor type for use with leds.set_color + */ +typedef struct LEDColor { + uint8_t r, g, b + #if HAS_WHITE_LED + , w + #if ENABLED(NEOPIXEL_LED) + , i + #endif + #endif + ; + LEDColor() : r(255), g(255), b(255) + #if HAS_WHITE_LED + , w(255) + #if ENABLED(NEOPIXEL_LED) + , i(NEOPIXEL_BRIGHTNESS) + #endif + #endif + {} + LEDColor(uint8_t r, uint8_t g, uint8_t b + #if HAS_WHITE_LED + , uint8_t w=0 + #if ENABLED(NEOPIXEL_LED) + , uint8_t i=NEOPIXEL_BRIGHTNESS + #endif + #endif + ) : r(r), g(g), b(b) + #if HAS_WHITE_LED + , w(w) + #if ENABLED(NEOPIXEL_LED) + , i(i) + #endif + #endif + {} + LEDColor& operator=(const LEDColor &right) { + if (this != &right) memcpy(this, &right, sizeof(LEDColor)); + return *this; + } + bool operator==(const LEDColor &right) { + if (this == &right) return true; + return 0 == memcmp(this, &right, sizeof(LEDColor)); + } + bool operator!=(const LEDColor &right) { return !operator==(right); } + bool is_off() const { + return 3 > r + g + b + #if HAS_WHITE_LED + + w + #endif + ; + } +} LEDColor; + +/** + * Color helpers and presets + */ +#if HAS_WHITE_LED + #define LEDColorWhite() LEDColor(0, 0, 0, 255) + #if ENABLED(NEOPIXEL_LED) + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B, W, I) + #else + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B, W) + #endif +#else + #define MakeLEDColor(R,G,B,W,I) LEDColor(R, G, B) + #define LEDColorWhite() LEDColor(255, 255, 255) +#endif +#define LEDColorOff() LEDColor( 0, 0, 0) +#define LEDColorRed() LEDColor(255, 0, 0) +#define LEDColorOrange() LEDColor(255, 80, 0) +#define LEDColorYellow() LEDColor(255, 255, 0) +#define LEDColorGreen() LEDColor( 0, 255, 0) +#define LEDColorBlue() LEDColor( 0, 0, 255) +#define LEDColorIndigo() LEDColor( 0, 255, 255) +#define LEDColorViolet() LEDColor(255, 0, 255) + +class LEDLights { +public: + LEDLights() {} // ctor + + static void setup(); // init() + + static void set_color(const LEDColor &color + #if ENABLED(NEOPIXEL_LED) + , bool isSequence=false + #endif + ); + + FORCE_INLINE void set_color(uint8_t r, uint8_t g, uint8_t b + #if HAS_WHITE_LED + , uint8_t w=0 + #if ENABLED(NEOPIXEL_LED) + , uint8_t i=NEOPIXEL_BRIGHTNESS + #endif + #endif + #if ENABLED(NEOPIXEL_LED) + , bool isSequence=false + #endif + ) { + set_color(MakeLEDColor(r, g, b, w, i) + #if ENABLED(NEOPIXEL_LED) + , isSequence + #endif + ); + } + + static void set_white(); + FORCE_INLINE static void set_off() { set_color(LEDColorOff()); } + FORCE_INLINE static void set_green() { set_color(LEDColorGreen()); } + + #if ENABLED(LED_COLOR_PRESETS) + static const LEDColor defaultLEDColor; + FORCE_INLINE static void set_default() { set_color(defaultLEDColor); } + FORCE_INLINE static void set_red() { set_color(LEDColorRed()); } + FORCE_INLINE static void set_orange() { set_color(LEDColorOrange()); } + FORCE_INLINE static void set_yellow() { set_color(LEDColorYellow()); } + FORCE_INLINE static void set_blue() { set_color(LEDColorBlue()); } + FORCE_INLINE static void set_indigo() { set_color(LEDColorIndigo()); } + FORCE_INLINE static void set_violet() { set_color(LEDColorViolet()); } + #endif + + #if ENABLED(LED_CONTROL_MENU) + static LEDColor color; // last non-off color + static bool lights_on; // the last set color was "on" + static void toggle(); // swap "off" with color + FORCE_INLINE static void update() { set_color(color); } + #endif +}; + +extern LEDLights leds; + +#endif // __LEDS_H__ diff --git a/Marlin/macros.h b/Marlin/macros.h index 05433597fb..253ba6011d 100644 --- a/Marlin/macros.h +++ b/Marlin/macros.h @@ -28,6 +28,13 @@ #define ABC 3 #define XYZ 3 +#define _XMIN_ 100 +#define _YMIN_ 200 +#define _ZMIN_ 300 +#define _XMAX_ 101 +#define _YMAX_ 201 +#define _ZMAX_ 301 + #define FORCE_INLINE __attribute__((always_inline)) inline #define _UNUSED __attribute__((unused)) #define _O0 __attribute__((optimize("O0"))) @@ -110,7 +117,11 @@ #define DEGREES(r) ((r)*180.0/M_PI) #define HYPOT2(x,y) (sq(x)+sq(y)) +#define CIRCLE_AREA(R) (M_PI * sq(R)) +#define CIRCLE_CIRC(R) (2.0 * M_PI * (R)) + #define SIGN(a) ((a>0)-(a<0)) +#define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1))) // Macros to contrain values #define NOLESS(v,n) do{ if (v < n) v = n; }while(0) @@ -177,6 +188,9 @@ #define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0) #define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON)) +#define MMM_TO_MMS(MM_M) ((MM_M)/60.0) +#define MMS_TO_MMM(MM_S) ((MM_S)*60.0) + #define NOOP do{} while(0) #define CEILING(x,y) (((x) + (y) - 1) / (y)) diff --git a/Marlin/mesh_bed_leveling.cpp b/Marlin/mesh_bed_leveling.cpp index 3da19d97ed..27344599b4 100644 --- a/Marlin/mesh_bed_leveling.cpp +++ b/Marlin/mesh_bed_leveling.cpp @@ -26,7 +26,7 @@ mesh_bed_leveling mbl; - uint8_t mesh_bed_leveling::status; + bool mesh_bed_leveling::has_mesh; float mesh_bed_leveling::z_offset, mesh_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], @@ -42,7 +42,7 @@ } void mesh_bed_leveling::reset() { - status = MBL_STATUS_NONE; + has_mesh = false; z_offset = 0; ZERO(z_values); } diff --git a/Marlin/mesh_bed_leveling.h b/Marlin/mesh_bed_leveling.h index f7b701bf28..87afeb5586 100644 --- a/Marlin/mesh_bed_leveling.h +++ b/Marlin/mesh_bed_leveling.h @@ -33,18 +33,12 @@ MeshReset }; - enum MBLStatus { - MBL_STATUS_NONE = 0, - MBL_STATUS_HAS_MESH_BIT = 0, - MBL_STATUS_ACTIVE_BIT = 1 - }; - #define MESH_X_DIST ((MESH_MAX_X - (MESH_MIN_X)) / (GRID_MAX_POINTS_X - 1)) #define MESH_Y_DIST ((MESH_MAX_Y - (MESH_MIN_Y)) / (GRID_MAX_POINTS_Y - 1)) class mesh_bed_leveling { public: - static uint8_t status; // Has Mesh and Is Active bits + static bool has_mesh; static float z_offset, z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], index_to_xpos[GRID_MAX_POINTS_X], @@ -56,11 +50,6 @@ static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; } - static bool active() { return TEST(status, MBL_STATUS_ACTIVE_BIT); } - static void set_active(const bool onOff) { onOff ? SBI(status, MBL_STATUS_ACTIVE_BIT) : CBI(status, MBL_STATUS_ACTIVE_BIT); } - static bool has_mesh() { return TEST(status, MBL_STATUS_HAS_MESH_BIT); } - static void set_has_mesh(const bool onOff) { onOff ? SBI(status, MBL_STATUS_HAS_MESH_BIT) : CBI(status, MBL_STATUS_HAS_MESH_BIT); } - static inline void zigzag(const int8_t index, int8_t &px, int8_t &py) { px = index % (GRID_MAX_POINTS_X); py = index / (GRID_MAX_POINTS_X); diff --git a/Marlin/neopixel.cpp b/Marlin/neopixel.cpp new file mode 100644 index 0000000000..8d8a5445e8 --- /dev/null +++ b/Marlin/neopixel.cpp @@ -0,0 +1,60 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * neopixel.cpp + */ + +#include "MarlinConfig.h" + +#if ENABLED(NEOPIXEL_LED) + +#include "neopixel.h" + +Adafruit_NeoPixel pixels(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800); + +void set_neopixel_color(const uint32_t color) { + for (uint16_t i = 0; i < pixels.numPixels(); ++i) + pixels.setPixelColor(i, color); + pixels.show(); +} + +void setup_neopixel() { + SET_OUTPUT(NEOPIXEL_PIN); + pixels.setBrightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range + pixels.begin(); + pixels.show(); // initialize to all off + + #if ENABLED(NEOPIXEL_STARTUP_TEST) + safe_delay(1000); + set_neopixel_color(pixels.Color(255, 0, 0, 0)); // red + safe_delay(1000); + set_neopixel_color(pixels.Color(0, 255, 0, 0)); // green + safe_delay(1000); + set_neopixel_color(pixels.Color(0, 0, 255, 0)); // blue + safe_delay(1000); + #endif + set_neopixel_color(pixels.Color(NEO_WHITE)); // white +} + +#endif // NEOPIXEL_LED + diff --git a/Marlin/neopixel.h b/Marlin/neopixel.h new file mode 100644 index 0000000000..b7ed45c827 --- /dev/null +++ b/Marlin/neopixel.h @@ -0,0 +1,44 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * neopixel.h + */ + +#include "MarlinConfig.h" + +#define NEOPIXEL_IS_RGB (NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR) +#define NEOPIXEL_IS_RGBW !NEOPIXEL_IS_RGB + +#if NEOPIXEL_IS_RGB + #define NEO_WHITE 255, 255, 255, 0 +#else + #define NEO_WHITE 0, 0, 0, 255 +#endif + +#include +#include + +void setup_neopixel(); +void set_neopixel_color(const uint32_t color); + +extern Adafruit_NeoPixel pixels; diff --git a/Marlin/nozzle.cpp b/Marlin/nozzle.cpp index eec8bfa39a..2967c0ce60 100644 --- a/Marlin/nozzle.cpp +++ b/Marlin/nozzle.cpp @@ -1,238 +1,185 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) + #include "nozzle.h" #include "Marlin.h" #include "point_t.h" -/** - * @brief Stroke clean pattern - * @details Wipes the nozzle back and forth in a linear movement - * - * @param start point_t defining the starting point - * @param end point_t defining the ending point - * @param strokes number of strokes to execute - */ -void Nozzle::stroke( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) +#if ENABLED(NOZZLE_CLEAN_FEATURE) + /** + * @brief Stroke clean pattern + * @details Wipes the nozzle back and forth in a linear movement + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + */ + void Nozzle::stroke(const point_t &start, const point_t &end, const uint8_t &strokes) { #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif // Move to the starting point - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); + do_blocking_move_to(start.x, start.y, start.z); // Start the stroke pattern - for (uint8_t i = 0; i < (strokes >>1); i++) { + for (uint8_t i = 0; i < (strokes >> 1); i++) { do_blocking_move_to_xy(end.x, end.y); do_blocking_move_to_xy(start.x, start.y); } #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - do_blocking_move_to(initial.x, initial.y, initial.z); - #endif // NOZZLE_CLEAN_GOBACK + do_blocking_move_to(ix, iy, iz); + #endif + } - #endif // NOZZLE_CLEAN_FEATURE -} - -/** - * @brief Zig-zag clean pattern - * @details Apply a zig-zag cleanning pattern - * - * @param start point_t defining the starting point - * @param end point_t defining the ending point - * @param strokes number of strokes to execute - * @param objects number of objects to create - */ -void Nozzle::zigzag( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes, - _UNUSED uint8_t const &objects -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) - const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude - P = (nozzle_clean_horizontal ? nozzle_clean_length : nozzle_clean_height) / (objects << 1); // Period - - // Don't allow impossible triangles - if (A <= 0.0f || P <= 0.0f ) return; + /** + * @brief Zig-zag clean pattern + * @details Apply a zig-zag cleaning pattern + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + * @param objects number of triangles to do + */ + void Nozzle::zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) { + const float diffx = end.x - start.x, diffy = end.y - start.y; + if (!diffx || !diffy) return; #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif + do_blocking_move_to(start.x, start.y, start.z); + + const uint8_t zigs = objects << 1; + const bool horiz = FABS(diffx) >= FABS(diffy); // Do a horizontal wipe? + const float P = (horiz ? diffx : diffy) / zigs; // Period of each zig / zag + const point_t *side; for (uint8_t j = 0; j < strokes; j++) { - for (uint8_t i = 0; i < (objects << 1); i++) { - float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - - do_blocking_move_to_xy(x, y); - if (i == 0) do_blocking_move_to_z(start.z); + for (int8_t i = 0; i < zigs; i++) { + side = (i & 1) ? &end : &start; + if (horiz) + do_blocking_move_to_xy(start.x + i * P, side->y); + else + do_blocking_move_to_xy(side->x, start.y + i * P); } - - for (int i = (objects << 1); i > -1; i--) { - float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); - - do_blocking_move_to_xy(x, y); + for (int8_t i = zigs; i >= 0; i--) { + side = (i & 1) ? &end : &start; + if (horiz) + do_blocking_move_to_xy(start.x + i * P, side->y); + else + do_blocking_move_to_xy(side->x, start.y + i * P); } } #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - #endif // NOZZLE_CLEAN_GOBACK + do_blocking_move_to(ix, iy, iz); + #endif + } - #endif // NOZZLE_CLEAN_FEATURE -} - - -/** - * @brief Circular clean pattern - * @details Apply a circular cleaning pattern - * - * @param start point_t defining the middle of circle - * @param strokes number of strokes to execute - * @param radius radius of circle - */ -void Nozzle::circle( - _UNUSED point_t const &start, - _UNUSED point_t const &middle, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) + /** + * @brief Circular clean pattern + * @details Apply a circular cleaning pattern + * + * @param start point_t defining the middle of circle + * @param strokes number of strokes to execute + * @param radius radius of circle + */ + void Nozzle::circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) { if (strokes == 0) return; #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif // NOZZLE_CLEAN_GOBACK + const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS]; + #endif - if (start.z <= current_position[Z_AXIS]) { - // Order of movement is pretty darn important here - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); - } - else { - do_blocking_move_to_z(start.z); - do_blocking_move_to_xy(start.x, start.y); - } + do_blocking_move_to(start.x, start.y, start.z); - float x, y; - for (uint8_t s = 0; s < strokes; s++) { - for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) { - x = middle.x + sin((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; - y = middle.y + cos((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; - - do_blocking_move_to_xy(x, y); - } - } + for (uint8_t s = 0; s < strokes; s++) + for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) + do_blocking_move_to_xy( + middle.x + sin((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius, + middle.y + cos((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius + ); // Let's be safe do_blocking_move_to_xy(start.x, start.y); #if ENABLED(NOZZLE_CLEAN_GOBACK) - // Move the nozzle to the initial point - if (start.z <= initial.z) { - // As above order is important - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - } - else { - do_blocking_move_to_xy(initial.x, initial.y); - do_blocking_move_to_z(initial.z); - } - #endif // NOZZLE_CLEAN_GOBACK - - #endif // NOZZLE_CLEAN_FEATURE -} - -/** - * @brief Clean the nozzle - * @details Starts the selected clean procedure pattern - * - * @param pattern one of the available patterns - * @param argument depends on the cleaning pattern - */ -void Nozzle::clean( - _UNUSED uint8_t const &pattern, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius, - _UNUSED uint8_t const &objects -) { - #if ENABLED(NOZZLE_CLEAN_FEATURE) - #if ENABLED(DELTA) - if (current_position[Z_AXIS] > delta_clip_start_height) - do_blocking_move_to_z(delta_clip_start_height); + do_blocking_move_to(ix, iy, iz); #endif + } + + /** + * @brief Clean the nozzle + * @details Starts the selected clean procedure pattern + * + * @param pattern one of the available patterns + * @param argument depends on the cleaning pattern + */ + void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects/*=0*/) { switch (pattern) { case 1: - Nozzle::zigzag( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_END_POINT, strokes, objects); + zigzag(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes, objects); break; case 2: - Nozzle::circle( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); + circle(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); break; default: - Nozzle::stroke( - NOZZLE_CLEAN_START_POINT, - NOZZLE_CLEAN_END_POINT, strokes); + stroke(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes); } - #endif // NOZZLE_CLEAN_FEATURE -} + } -void Nozzle::park( - _UNUSED uint8_t const &z_action -) { - #if ENABLED(NOZZLE_PARK_FEATURE) - float const z = current_position[Z_AXIS]; - point_t const park = NOZZLE_PARK_POINT; +#endif // NOZZLE_CLEAN_FEATURE - switch(z_action) { - case 1: // force Z-park height +#if ENABLED(NOZZLE_PARK_FEATURE) + + void Nozzle::park(const uint8_t &z_action) { + const point_t park = NOZZLE_PARK_POINT; + + switch (z_action) { + case 1: // Go to Z-park height do_blocking_move_to_z(park.z); break; case 2: // Raise by Z-park height - do_blocking_move_to_z( - (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z); + do_blocking_move_to_z(min(current_position[Z_AXIS] + park.z, Z_MAX_POS)); break; - default: // Raise to Z-park height if lower - if (current_position[Z_AXIS] < park.z) - do_blocking_move_to_z(park.z); + default: // Raise to at least the Z-park height + do_blocking_move_to_z(max(park.z, current_position[Z_AXIS])); } do_blocking_move_to_xy(park.x, park.y); + } - #endif // NOZZLE_PARK_FEATURE -} +#endif // NOZZLE_PARK_FEATURE + +#endif // NOZZLE_CLEAN_FEATURE || NOZZLE_PARK_FEATURE diff --git a/Marlin/nozzle.h b/Marlin/nozzle.h index 2fbe98fb06..6024fd3443 100644 --- a/Marlin/nozzle.h +++ b/Marlin/nozzle.h @@ -26,14 +26,6 @@ #include "Marlin.h" #include "point_t.h" -#if ENABLED(NOZZLE_CLEAN_FEATURE) - constexpr float nozzle_clean_start_point[4] = NOZZLE_CLEAN_START_POINT, - nozzle_clean_end_point[4] = NOZZLE_CLEAN_END_POINT, - nozzle_clean_length = FABS(nozzle_clean_start_point[X_AXIS] - nozzle_clean_end_point[X_AXIS]), //abs x size of wipe pad - nozzle_clean_height = FABS(nozzle_clean_start_point[Y_AXIS] - nozzle_clean_end_point[Y_AXIS]); //abs y size of wipe pad - constexpr bool nozzle_clean_horizontal = nozzle_clean_length >= nozzle_clean_height; //whether to zig-zag horizontally or vertically -#endif // NOZZLE_CLEAN_FEATURE - /** * @brief Nozzle class * @@ -41,6 +33,9 @@ */ class Nozzle { private: + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + /** * @brief Stroke clean pattern * @details Wipes the nozzle back and forth in a linear movement @@ -49,11 +44,7 @@ class Nozzle { * @param end point_t defining the ending point * @param strokes number of strokes to execute */ - static void stroke( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes - ) _Os; + static void stroke(const point_t &start, const point_t &end, const uint8_t &strokes) _Os; /** * @brief Zig-zag clean pattern @@ -64,12 +55,7 @@ class Nozzle { * @param strokes number of strokes to execute * @param objects number of objects to create */ - static void zigzag( - _UNUSED point_t const &start, - _UNUSED point_t const &end, - _UNUSED uint8_t const &strokes, - _UNUSED uint8_t const &objects - ) _Os; + static void zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) _Os; /** * @brief Circular clean pattern @@ -79,14 +65,14 @@ class Nozzle { * @param strokes number of strokes to execute * @param radius radius of circle */ - static void circle( - _UNUSED point_t const &start, - _UNUSED point_t const &middle, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius - ) _Os; + static void circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) _Os; + + #endif // NOZZLE_CLEAN_FEATURE public: + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + /** * @brief Clean the nozzle * @details Starts the selected clean procedure pattern @@ -94,16 +80,15 @@ class Nozzle { * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - static void clean( - _UNUSED uint8_t const &pattern, - _UNUSED uint8_t const &strokes, - _UNUSED float const &radius, - _UNUSED uint8_t const &objects = 0 - ) _Os; + static void clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects=0) _Os; - static void park( - _UNUSED uint8_t const &z_action - ) _Os; + #endif // NOZZLE_CLEAN_FEATURE + + #if ENABLED(NOZZLE_PARK_FEATURE) + + static void park(const uint8_t &z_action) _Os; + + #endif }; -#endif +#endif // __NOZZLE_H__ diff --git a/Marlin/pca9632.cpp b/Marlin/pca9632.cpp index 37f7bd7df7..2b4ee7f40b 100644 --- a/Marlin/pca9632.cpp +++ b/Marlin/pca9632.cpp @@ -20,7 +20,7 @@ * */ -/* +/** * Driver for the Philips PCA9632 LED driver. * Written by Robert Mendon Feb 2017. */ @@ -30,12 +30,13 @@ #if ENABLED(PCA9632) #include "pca9632.h" +#include "leds.h" +#include #define PCA9632_MODE1_VALUE 0b00000001 //(ALLCALL) #define PCA9632_MODE2_VALUE 0b00010101 //(DIMMING, INVERT, CHANGE ON STOP,TOTEM) #define PCA9632_LEDOUT_VALUE 0b00101010 - /* Register addresses */ #define PCA9632_MODE1 0x00 #define PCA9632_MODE2 0x01 @@ -98,7 +99,7 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const } #endif -void PCA9632_SetColor(const byte r, const byte g, const byte b) { +void pca9632_set_led_color(const LEDColor &color) { if (!PCA_init) { PCA_init = 1; Wire.begin(); @@ -106,11 +107,11 @@ void PCA9632_SetColor(const byte r, const byte g, const byte b) { PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE); } - const byte LEDOUT = (r ? LED_PWM << PCA9632_RED : 0) - | (g ? LED_PWM << PCA9632_GRN : 0) - | (b ? LED_PWM << PCA9632_BLU : 0); + const byte LEDOUT = (color.r ? LED_PWM << PCA9632_RED : 0) + | (color.g ? LED_PWM << PCA9632_GRN : 0) + | (color.b ? LED_PWM << PCA9632_BLU : 0); - PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, r, g, b); + PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, color.r, color.g, color.b); PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT); } diff --git a/Marlin/pca9632.h b/Marlin/pca9632.h index b8c78f065d..4d98267beb 100644 --- a/Marlin/pca9632.h +++ b/Marlin/pca9632.h @@ -20,7 +20,7 @@ * */ -/* +/** * Driver for the Philips PCA9632 LED driver. * Written by Robert Mendon Feb 2017. */ @@ -28,9 +28,9 @@ #ifndef __PCA9632_H__ #define __PCA9632_H__ -#include "Arduino.h" -#include "Wire.h" +struct LEDColor; +typedef LEDColor LEDColor; -void PCA9632_SetColor(const byte r, const byte g, const byte b); +void pca9632_set_led_color(const LEDColor &color); #endif // __PCA9632_H__ diff --git a/Marlin/pins.h b/Marlin/pins.h index fbf2331da1..b26d8755e2 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -71,6 +71,21 @@ #elif MB(RAMPS_14_SF) #define IS_RAMPS_SF #include "pins_RAMPS.h" +#elif MB(RAMPS_PLUS_EFB) + #define IS_RAMPS_EFB + #include "pins_RAMPS_PLUS.h" +#elif MB(RAMPS_PLUS_EEB) + #define IS_RAMPS_EEB + #include "pins_RAMPS_PLUS.h" +#elif MB(RAMPS_PLUS_EFF) + #define IS_RAMPS_EFF + #include "pins_RAMPS_PLUS.h" +#elif MB(RAMPS_PLUS_EEF) + #define IS_RAMPS_EEF + #include "pins_RAMPS_PLUS.h" +#elif MB(RAMPS_PLUS_SF) + #define IS_RAMPS_SF + #include "pins_RAMPS_PLUS.h" // // RAMPS Derivatives - ATmega1280, ATmega2560 @@ -90,6 +105,8 @@ #include "pins_MKS_BASE.h" // ATmega1280, ATmega2560 #elif MB(MKS_13) #include "pins_MKS_13.h" // ATmega1280, ATmega2560 +#elif MB(MKS_GEN_L) + #include "pins_MKS_GEN_L.h" // ATmega1280, ATmega2560 #elif MB(ZRIB_V20) #include "pins_ZRIB_V20.h" // ATmega1280, ATmega2560 (MKS_13) #elif MB(FELIX2) @@ -114,6 +131,8 @@ #include "pins_RUMBA.h" // ATmega2560 #elif MB(BQ_ZUM_MEGA_3D) #include "pins_BQ_ZUM_MEGA_3D.h" // ATmega2560 +#elif MB(MAKEBOARD_MINI) + #include "pins_MAKEBOARD_MINI.h" // ATmega2560 // // Other ATmega1280, ATmega2560 @@ -133,14 +152,11 @@ #include "pins_MEGATRONICS.h" // ATmega2560 #elif MB(MEGATRONICS_2) #include "pins_MEGATRONICS_2.h" // ATmega2560 -#elif MB(MEGATRONICS_3) - #include "pins_MEGATRONICS_3.h" // ATmega2560 -#elif MB(MEGATRONICS_31) - #define MEGATRONICS_31 +#elif MB(MEGATRONICS_3) || MB(MEGATRONICS_31) #include "pins_MEGATRONICS_3.h" // ATmega2560 #elif MB(RAMBO) #include "pins_RAMBO.h" // ATmega2560 -#elif MB(MINIRAMBO) +#elif MB(MINIRAMBO) || MB(MINIRAMBO_10A) #include "pins_MINIRAMBO.h" // ATmega2560 #elif MB(ELEFU_3) #include "pins_ELEFU_3.h" // ATmega2560 @@ -154,6 +170,8 @@ #include "pins_GT2560_REV_A.h" // ATmega1280, ATmega2560 #elif MB(GT2560_REV_A_PLUS) #include "pins_GT2560_REV_A_PLUS.h" // ATmega1280, ATmega2560 +#elif MB(SILVER_GATE) + #include "pins_SILVER_GATE.h" // ATmega2561 // // ATmega1281, ATmega2561 @@ -254,18 +272,63 @@ #ifndef Z_MS2_PIN #define Z_MS2_PIN -1 #endif +#ifndef E0_STEP_PIN + #define E0_STEP_PIN -1 +#endif +#ifndef E0_DIR_PIN + #define E0_DIR_PIN -1 +#endif +#ifndef E0_ENABLE_PIN + #define E0_ENABLE_PIN -1 +#endif #ifndef E0_MS1_PIN #define E0_MS1_PIN -1 #endif #ifndef E0_MS2_PIN #define E0_MS2_PIN -1 #endif +#ifndef E1_STEP_PIN + #define E1_STEP_PIN -1 +#endif +#ifndef E1_DIR_PIN + #define E1_DIR_PIN -1 +#endif +#ifndef E1_ENABLE_PIN + #define E1_ENABLE_PIN -1 +#endif #ifndef E1_MS1_PIN #define E1_MS1_PIN -1 #endif #ifndef E1_MS2_PIN #define E1_MS2_PIN -1 #endif +#ifndef E2_STEP_PIN + #define E2_STEP_PIN -1 +#endif +#ifndef E2_DIR_PIN + #define E2_DIR_PIN -1 +#endif +#ifndef E2_ENABLE_PIN + #define E2_ENABLE_PIN -1 +#endif +#ifndef E3_STEP_PIN + #define E3_STEP_PIN -1 +#endif +#ifndef E3_DIR_PIN + #define E3_DIR_PIN -1 +#endif +#ifndef E3_ENABLE_PIN + #define E3_ENABLE_PIN -1 +#endif +#ifndef E4_STEP_PIN + #define E4_STEP_PIN -1 +#endif +#ifndef E4_DIR_PIN + #define E4_DIR_PIN -1 +#endif +#ifndef E4_ENABLE_PIN + #define E4_ENABLE_PIN -1 +#endif #ifndef FAN_PIN #define FAN_PIN -1 @@ -551,7 +614,7 @@ #define X2_STEP_PIN _EPIN(E_STEPPERS, STEP) #define X2_DIR_PIN _EPIN(E_STEPPERS, DIR) #define X2_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE) - #if X2_ENABLE_PIN == 0 + #if E_STEPPERS > 4 || !PIN_EXISTS(X2_ENABLE) #error "No E stepper plug left for X2!" #endif #endif @@ -568,7 +631,7 @@ #define Y2_STEP_PIN _EPIN(Y2_E_INDEX, STEP) #define Y2_DIR_PIN _EPIN(Y2_E_INDEX, DIR) #define Y2_ENABLE_PIN _EPIN(Y2_E_INDEX, ENABLE) - #if Y2_ENABLE_PIN == 0 + #if Y2_E_INDEX > 4 || !PIN_EXISTS(Y2_ENABLE) #error "No E stepper plug left for Y2!" #endif #endif @@ -585,7 +648,7 @@ #define Z2_STEP_PIN _EPIN(Z2_E_INDEX, STEP) #define Z2_DIR_PIN _EPIN(Z2_E_INDEX, DIR) #define Z2_ENABLE_PIN _EPIN(Z2_E_INDEX, ENABLE) - #if Z2_ENABLE_PIN == 0 + #if Z2_E_INDEX > 4 || !PIN_EXISTS(Z2_ENABLE) #error "No E stepper plug left for Z2!" #endif #endif diff --git a/Marlin/pinsDebug.h b/Marlin/pinsDebug.h index 56f0916d20..239e9c4b16 100644 --- a/Marlin/pinsDebug.h +++ b/Marlin/pinsDebug.h @@ -102,10 +102,7 @@ const PinInfo pin_array[] PROGMEM = { }; -#define AVR_ATmega2560_FAMILY_PLUS_70 (MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D \ -|| MOTHERBOARD == BOARD_MIGHTYBOARD_REVE \ -|| MOTHERBOARD == BOARD_MINIRAMBO \ -|| MOTHERBOARD == BOARD_SCOOVO_X9H) +#define AVR_ATmega2560_FAMILY_PLUS_70 (MB(BQ_ZUM_MEGA_3D) || MB(MIGHTYBOARD_REVE) || MB(MINIRAMBO) || MB(SCOOVO_X9H)) #if AVR_AT90USB1286_FAMILY // Working with Teensyduino extension so need to re-define some things diff --git a/Marlin/pinsDebug_list.h b/Marlin/pinsDebug_list.h index b4cc4c29f8..e6de27a815 100644 --- a/Marlin/pinsDebug_list.h +++ b/Marlin/pinsDebug_list.h @@ -776,4 +776,69 @@ #if PIN_EXISTS(Z2_STEP) REPORT_NAME_DIGITAL(Z2_STEP_PIN, __LINE__ ) #endif - +#if PIN_EXISTS(X_SERIAL_TX) + REPORT_NAME_DIGITAL(X_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_SERIAL_RX) + REPORT_NAME_DIGITAL(X_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X2_SERIAL_TX) + REPORT_NAME_DIGITAL(X2_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X2_SERIAL_RX) + REPORT_NAME_DIGITAL(X2_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_SERIAL_TX) + REPORT_NAME_DIGITAL(Y_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_SERIAL_RX) + REPORT_NAME_DIGITAL(Y_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y2_SERIAL_TX) + REPORT_NAME_DIGITAL(Y2_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y2_SERIAL_RX) + REPORT_NAME_DIGITAL(Y2_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_SERIAL_TX) + REPORT_NAME_DIGITAL(Z_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_SERIAL_RX) + REPORT_NAME_DIGITAL(Z_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z2_SERIAL_TX) + REPORT_NAME_DIGITAL(Z2_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z2_SERIAL_RX) + REPORT_NAME_DIGITAL(Z2_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_SERIAL_TX) + REPORT_NAME_DIGITAL(E0_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_SERIAL_RX) + REPORT_NAME_DIGITAL(E0_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_SERIAL_TX) + REPORT_NAME_DIGITAL(E1_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_SERIAL_RX) + REPORT_NAME_DIGITAL(E1_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_SERIAL_TX) + REPORT_NAME_DIGITAL(E2_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_SERIAL_RX) + REPORT_NAME_DIGITAL(E2_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_SERIAL_TX) + REPORT_NAME_DIGITAL(E3_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_SERIAL_RX) + REPORT_NAME_DIGITAL(E3_SERIAL_RX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_SERIAL_TX) + REPORT_NAME_DIGITAL(E4_SERIAL_TX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_SERIAL_RX) + REPORT_NAME_DIGITAL(E4_SERIAL_RX_PIN, __LINE__ ) +#endif diff --git a/Marlin/pinsDebug_plus_70.h b/Marlin/pinsDebug_plus_70.h index 1a905bd463..c18c595ec9 100644 --- a/Marlin/pinsDebug_plus_70.h +++ b/Marlin/pinsDebug_plus_70.h @@ -29,13 +29,13 @@ #define __PINSDEBUG_PLUS_70_H__ #undef NUM_DIGITAL_PINS -#if MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D +#if MB(BQ_ZUM_MEGA_3D) #define NUM_DIGITAL_PINS 85 -#elif MOTHERBOARD == BOARD_MIGHTYBOARD_REVE +#elif MB(MIGHTYBOARD_REVE) #define NUM_DIGITAL_PINS 80 -#elif MOTHERBOARD == BOARD_MINIRAMBO +#elif MB(MINIRAMBO) #define NUM_DIGITAL_PINS 85 -#elif MOTHERBOARD == BOARD_SCOOVO_X9H +#elif MB(SCOOVO_X9H) #define NUM_DIGITAL_PINS 85 #endif diff --git a/Marlin/pins_5DPRINT.h b/Marlin/pins_5DPRINT.h index e99047f66f..f5e0f4d48a 100755 --- a/Marlin/pins_5DPRINT.h +++ b/Marlin/pins_5DPRINT.h @@ -74,8 +74,6 @@ #define DEFAULT_MACHINE_NAME "Makibox" #define BOARD_NAME "5DPrint D8" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_ANET_10.h b/Marlin/pins_ANET_10.h index 8668681bf4..fcac4c0908 100644 --- a/Marlin/pins_ANET_10.h +++ b/Marlin/pins_ANET_10.h @@ -88,7 +88,7 @@ * Many thanks to Hans Raaf (@oderwat) for developing the Anet-specific software and supporting the Anet community. */ -#if !defined(__AVR_ATmega1284P__) +#ifndef __AVR_ATmega1284P__ #error "Oops! Make sure you have 'Anet V1.0', 'Anet V1.0 (Optiboot)' or 'Sanguino' selected from the 'Tools -> Boards' menu." #endif @@ -96,8 +96,6 @@ #define BOARD_NAME "Anet" #endif -#define LARGE_FLASH true - // // Limit Switches // @@ -147,44 +145,45 @@ * LCD / Controller * * Only the following displays are supported: - * ANET_KEYPAD_LCD + * ZONESTAR_LCD * ANET_FULL_GRAPHICS_LCD * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER -*/ + */ #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) #define LCD_SDSS 28 #if ENABLED(ADC_KEYPAD) - #define SERVO0_PIN 27 // free for BLTouch/3D-Touch - #define LCD_PINS_RS 28 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 10 - #define LCD_PINS_D5 11 - #define LCD_PINS_D6 16 - #define LCD_PINS_D7 17 - #define BTN_EN1 -1 - #define BTN_EN2 -1 - #define BTN_ENC -1 - #define ADC_KEYPAD_PIN 1 - #define ENCODER_FEEDRATE_DEADZONE 2 + #define SERVO0_PIN 27 // free for BLTouch/3D-Touch + #define LCD_PINS_RS 28 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 10 + #define LCD_PINS_D5 11 + #define LCD_PINS_D6 16 + #define LCD_PINS_D7 17 + #define BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 + #define ADC_KEYPAD_PIN 1 #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(ANET_FULL_GRAPHICS_LCD) // Pin definitions for the Anet A6 Full Graphics display and the RepRapDiscount Full Graphics // display using an adapter board // https://go.aisler.net/benlye/anet-lcd-adapter/pcb // See below for alternative pin definitions for use with https://www.thingiverse.com/thing:2103748 - #define SERVO0_PIN 29 // free for BLTouch/3D-Touch - #define BEEPER_PIN 17 - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 28 - #define LCD_PINS_D4 30 - #define BTN_EN1 11 - #define BTN_EN2 10 - #define BTN_ENC 16 + #define SERVO0_PIN 29 // free for BLTouch/3D-Touch + #define BEEPER_PIN 17 + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 28 + #define LCD_PINS_D4 30 + #define BTN_EN1 11 + #define BTN_EN2 10 + #define BTN_ENC 16 #define ST7920_DELAY_1 DELAY_0_NOP #define ST7920_DELAY_2 DELAY_1_NOP #define ST7920_DELAY_3 DELAY_2_NOP #define STD_ENCODER_PULSES_PER_STEP 4 #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 #endif +#else + #define SERVO0_PIN 27 #endif // ULTRA_LCD && NEWPANEL /** @@ -210,7 +209,7 @@ * ===================== LCD PINOUTS ================================== * ==================================================================== * - * Anet V1.0 controller | ANET_KEYPAD_LCD | ANET_FULL_ | RepRapDiscount Full | Thingiverse RepRap wiring + * Anet V1.0 controller | ZONESTAR_LCD | ANET_FULL_ | RepRapDiscount Full | Thingiverse RepRap wiring * physical logical alt | | GRAPHICS_LCD | Graphics Display Wiring | http://www.thingiverse * pin pin functions | | | | .com/thing:2103748 *------------------------------------------------------------------------------------------------------------------------ diff --git a/Marlin/pins_BRAINWAVE_PRO.h b/Marlin/pins_BRAINWAVE_PRO.h index acf8642e04..872d868e10 100755 --- a/Marlin/pins_BRAINWAVE_PRO.h +++ b/Marlin/pins_BRAINWAVE_PRO.h @@ -80,8 +80,6 @@ #define BOARD_NAME "Brainwave Pro" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_CHEAPTRONIC.h b/Marlin/pins_CHEAPTRONIC.h index a354a279bf..6d1e45d870 100644 --- a/Marlin/pins_CHEAPTRONIC.h +++ b/Marlin/pins_CHEAPTRONIC.h @@ -29,8 +29,6 @@ #endif #define BOARD_NAME "Cheaptronic v1.0" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_CHEAPTRONICv2.h b/Marlin/pins_CHEAPTRONICv2.h index 257380dd66..b30d6d3bbc 100644 --- a/Marlin/pins_CHEAPTRONICv2.h +++ b/Marlin/pins_CHEAPTRONICv2.h @@ -31,8 +31,6 @@ #endif #define BOARD_NAME "Cheaptronic v2.0" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_CNCONTROLS_11.h b/Marlin/pins_CNCONTROLS_11.h index fdf6c317e5..265d1b6aa3 100644 --- a/Marlin/pins_CNCONTROLS_11.h +++ b/Marlin/pins_CNCONTROLS_11.h @@ -8,8 +8,6 @@ #define BOARD_NAME "CN Controls V11" -//#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_CNCONTROLS_12.h b/Marlin/pins_CNCONTROLS_12.h index 809d1a6db2..50c87cda68 100644 --- a/Marlin/pins_CNCONTROLS_12.h +++ b/Marlin/pins_CNCONTROLS_12.h @@ -8,8 +8,6 @@ #define BOARD_NAME "CN Controls V12" -//#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_GT2560_REV_A.h b/Marlin/pins_GT2560_REV_A.h index 0c420cfaa2..125acf8419 100644 --- a/Marlin/pins_GT2560_REV_A.h +++ b/Marlin/pins_GT2560_REV_A.h @@ -32,8 +32,6 @@ #define BOARD_NAME "GT2560 Rev.A" #define DEFAULT_MACHINE_NAME "Prusa i3 Pro B" -#define LARGE_FLASH true - // // Limit Switches // @@ -98,18 +96,23 @@ #if ENABLED(NEWPANEL) - #define LCD_PINS_RS 20 - #define LCD_PINS_ENABLE 17 - #define LCD_PINS_D4 16 - #define LCD_PINS_D5 21 - #define LCD_PINS_D6 5 - #define LCD_PINS_D7 6 + #if ENABLED(MKS_MINI_12864) + #define DOGLCD_A0 5 + #define DOGLCD_CS 21 + #define BTN_EN1 40 + #define BTN_EN2 42 + #else + #define LCD_PINS_RS 20 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 16 + #define LCD_PINS_D5 21 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 6 + #define BTN_EN1 42 + #define BTN_EN2 40 + #endif - // Buttons are directly attached - #define BTN_EN1 42 - #define BTN_EN2 40 #define BTN_ENC 19 - #define SD_DETECT_PIN 38 #else // !NEWPANEL diff --git a/Marlin/pins_MAKEBOARD_MINI.h b/Marlin/pins_MAKEBOARD_MINI.h new file mode 100644 index 0000000000..5dcf1e2180 --- /dev/null +++ b/Marlin/pins_MAKEBOARD_MINI.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +#include "pins_RAMPS.h" + +#undef BOARD_NAME +#define BOARD_NAME "MAKEBOARD_MINI" + +// +// Only 3 Limit Switch plugs on Micromake C1 +// +#undef X_MIN_PIN +#undef Y_MIN_PIN +#undef Z_MIN_PIN +#undef X_MAX_PIN +#undef Y_MAX_PIN +#undef Z_MAX_PIN +#define X_STOP_PIN 2 +#define Y_STOP_PIN 15 +#define Z_STOP_PIN 19 diff --git a/Marlin/pins_MEGATRONICS.h b/Marlin/pins_MEGATRONICS.h index ba97fa2556..702cf98865 100644 --- a/Marlin/pins_MEGATRONICS.h +++ b/Marlin/pins_MEGATRONICS.h @@ -29,8 +29,6 @@ #endif #define BOARD_NAME "Megatronics" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_MEGATRONICS_2.h b/Marlin/pins_MEGATRONICS_2.h index 6db1489bf9..2609d20653 100644 --- a/Marlin/pins_MEGATRONICS_2.h +++ b/Marlin/pins_MEGATRONICS_2.h @@ -29,8 +29,6 @@ #endif #define BOARD_NAME "Megatronics v2.0" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_MEGATRONICS_3.h b/Marlin/pins_MEGATRONICS_3.h index 2ebb209bcb..7b66361d3c 100644 --- a/Marlin/pins_MEGATRONICS_3.h +++ b/Marlin/pins_MEGATRONICS_3.h @@ -21,23 +21,19 @@ */ /** - * MegaTronics v3.0 pin assignments + * MegaTronics v3.0 / v3.1 pin assignments */ #ifndef __AVR_ATmega2560__ #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." #endif -#define MEGATRONICS_31 - -#if ENABLED(MEGATRONICS_31) - #define BOARD_NAME "Megatronics v3.1" +#if MB(MEGATRONICS_31) + #define BOARD_NAME "Megatronics v3.1" #else - #define BOARD_NAME "Megatronics v3.0" + #define BOARD_NAME "Megatronics v3.0" #endif -#define LARGE_FLASH true - // // Servos // @@ -163,10 +159,8 @@ #define SHIFT_OUT 34 #define SHIFT_EN 44 - #if ENABLED(MEGATRONICS_31) + #if MB(MEGATRONICS_31) #define SD_DETECT_PIN 56 - #else - #define SD_DETECT_PIN -1 #endif #endif diff --git a/Marlin/pins_MELZI_CREALITY.h b/Marlin/pins_MELZI_CREALITY.h index 7981e4a491..02f8491102 100644 --- a/Marlin/pins_MELZI_CREALITY.h +++ b/Marlin/pins_MELZI_CREALITY.h @@ -48,17 +48,22 @@ #undef LCD_PINS_D7 #undef FIL_RUNOUT_PIN -#define LCD_SDSS 31 // Smart Controller SD card reader (rather than the Melzi) -#define LCD_PINS_RS 28 // st9720 CS -#define LCD_PINS_ENABLE 17 // st9720 DAT -#define LCD_PINS_D4 30 // st9720 CLK -#define FIL_RUNOUT_PIN -1 // Uses Beeper/LED Pin Pulled to GND +#define LCD_SDSS 31 // Smart Controller SD card reader (rather than the Melzi) +#define LCD_PINS_RS 28 // st9720 CS +#define LCD_PINS_ENABLE 17 // st9720 DAT +#define LCD_PINS_D4 30 // st9720 CLK +#define FIL_RUNOUT_PIN -1 // Uses Beeper/LED Pin Pulled to GND // Alter timing for graphical display #define ST7920_DELAY_1 DELAY_2_NOP #define ST7920_DELAY_2 DELAY_2_NOP #define ST7920_DELAY_3 DELAY_2_NOP +#if ENABLED(MINIPANEL) + #undef DOGLCD_CS + #define DOGLCD_CS LCD_PINS_RS +#endif + /** PIN: 0 Port: B0 E0_DIR_PIN protected PIN: 1 Port: B1 E0_STEP_PIN protected diff --git a/Marlin/pins_MIGHTYBOARD_REVE.h b/Marlin/pins_MIGHTYBOARD_REVE.h index 5b5d6e7ed1..86be51add5 100644 --- a/Marlin/pins_MIGHTYBOARD_REVE.h +++ b/Marlin/pins_MIGHTYBOARD_REVE.h @@ -59,8 +59,6 @@ #define DEFAULT_MACHINE_NAME "MB Replicator" #define BOARD_NAME "Mightyboard" -#define LARGE_FLASH true - // // Servos // @@ -125,7 +123,7 @@ // // Temperature Sensors // -#define TEMP_BED_PIN 69 // K7 +#define TEMP_BED_PIN 15 // K7 - 69 / ADC15 - 15 // SPI for Max6675 or Max31855 Thermocouple // Uses a separate SPI bus diff --git a/Marlin/pins_MINIRAMBO.h b/Marlin/pins_MINIRAMBO.h index 9ff32207f9..b326112e68 100644 --- a/Marlin/pins_MINIRAMBO.h +++ b/Marlin/pins_MINIRAMBO.h @@ -25,11 +25,14 @@ */ #ifndef __AVR_ATmega2560__ - #error "Oops! Make sure you have 'Arduino Mega 2560 or Rambo' selected from the 'Tools -> Boards' menu." + #error "Oops! Make sure you have 'Rambo' selected from the 'Tools -> Boards' menu." #endif -#define BOARD_NAME "Mini Rambo" -#define LARGE_FLASH true +#if MB(MINIRAMBO_10A) + #define BOARD_NAME "Mini Rambo 1.0a" +#else + #define BOARD_NAME "Mini Rambo" +#endif // // Limit Switches @@ -67,10 +70,6 @@ #define E0_DIR_PIN 43 #define E0_ENABLE_PIN 26 -#define E1_STEP_PIN -1 -#define E1_DIR_PIN -1 -#define E1_ENABLE_PIN -1 - // Microstepping pins - Mapping not from fastio.h (?) #define X_MS1_PIN 40 #define X_MS2_PIN 41 @@ -102,7 +101,9 @@ // #define HEATER_0_PIN 3 #define HEATER_1_PIN 7 -#define HEATER_2_PIN 6 +#if !MB(MINIRAMBO_10A) + #define HEATER_2_PIN 6 +#endif #define HEATER_BED_PIN 4 #define FAN_PIN 8 @@ -113,7 +114,9 @@ // #define SDSS 53 #define LED_PIN 13 -#define CASE_LIGHT_PIN 9 +#if !MB(MINIRAMBO_10A) + #define CASE_LIGHT_PIN 9 +#endif // // M3/M4/M5 - Spindle/Laser Control @@ -128,33 +131,59 @@ // #define E_MUX0_PIN 17 #define E_MUX1_PIN 16 -#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 +#if !MB(MINIRAMBO_10A) + #define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78 +#endif // // LCD / Controller // #if ENABLED(ULTRA_LCD) - #define KILL_PIN 32 + #if !MB(MINIRAMBO_10A) + #define KILL_PIN 32 + #endif #if ENABLED(NEWPANEL) - // Beeper on AUX-4 - #define BEEPER_PIN 84 + #if MB(MINIRAMBO_10A) - #define LCD_PINS_RS 82 - #define LCD_PINS_ENABLE 18 - #define LCD_PINS_D4 19 - #define LCD_PINS_D5 70 - #define LCD_PINS_D6 85 - #define LCD_PINS_D7 71 + #define BEEPER_PIN 78 - // buttons are directly attached using AUX-2 - #define BTN_EN1 14 - #define BTN_EN2 72 - #define BTN_ENC 9 // the click + #define BTN_EN1 80 + #define BTN_EN2 73 + #define BTN_ENC 21 - #define SD_DETECT_PIN 15 + #define LCD_PINS_RS 38 + #define LCD_PINS_ENABLE 5 + #define LCD_PINS_D4 14 + #define LCD_PINS_D5 15 + #define LCD_PINS_D6 32 + #define LCD_PINS_D7 31 + + #define SD_DETECT_PIN 72 + + #else // !MINIRAMBO_10A + + // AUX-4 + #define BEEPER_PIN 84 + + // AUX-2 + #define BTN_EN1 14 + #define BTN_EN2 72 + #define BTN_ENC 9 + + #define LCD_PINS_RS 82 + #define LCD_PINS_ENABLE 18 + #define LCD_PINS_D4 19 + #define LCD_PINS_D5 70 + #define LCD_PINS_D6 85 + #define LCD_PINS_D7 71 + + #define SD_DETECT_PIN 15 + + #endif // !MINIRAMBO_10A #endif // NEWPANEL + #endif // ULTRA_LCD diff --git a/Marlin/pins_MINITRONICS.h b/Marlin/pins_MINITRONICS.h index f224f200be..d3ff9edbb0 100644 --- a/Marlin/pins_MINITRONICS.h +++ b/Marlin/pins_MINITRONICS.h @@ -40,8 +40,6 @@ #endif #define BOARD_NAME "Minitronics v1.0 / v1.1" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_MKS_GEN_L.h b/Marlin/pins_MKS_GEN_L.h new file mode 100644 index 0000000000..dd4568e152 --- /dev/null +++ b/Marlin/pins_MKS_GEN_L.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * MKS GEN L – Arduino Mega2560 with RAMPS v1.4 pin assignments + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS GEN L supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "MKS GEN L" + +// +// Heaters / Fans +// +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#include "pins_RAMPS.h" diff --git a/Marlin/pins_PRINTRBOARD.h b/Marlin/pins_PRINTRBOARD.h index 9681e0959e..93f4b2b69b 100755 --- a/Marlin/pins_PRINTRBOARD.h +++ b/Marlin/pins_PRINTRBOARD.h @@ -67,10 +67,8 @@ #define BOARD_NAME "Printrboard" -#define LARGE_FLASH true - // Disable JTAG pins so they can be used for the Extrudrboard -#define DISABLE_JTAG true +#define DISABLE_JTAG // // Limit Switches @@ -129,23 +127,6 @@ // LCD / Controller // #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) - // we have no buzzer installed - #define BEEPER_PIN -1 - - // LCD Pins - #if ENABLED(LCD_I2C_PANELOLU2) - #define BTN_EN1 3 // D3 RX1 JP2-7 - #define BTN_EN2 2 // D2 TX1 JP2-5 - #define BTN_ENC 41 // F3 JP2-4 - #define SDSS 38 // F0 B-THERM connector - use SD card on Panelolu2 - #else - #define BTN_EN1 10 // C0 JP11-12 - #define BTN_EN2 11 // C1 JP11-13 - #define BTN_ENC 12 // C2 JP11-14 - #endif - - // not connected - #define SD_DETECT_PIN -1 #define LCD_PINS_RS 9 // E1 JP11-11 #define LCD_PINS_ENABLE 8 // E0 JP11-10 @@ -154,24 +135,35 @@ #define LCD_PINS_D6 5 // D5 JP11-6 #define LCD_PINS_D7 4 // D4 JP11-5 + #if ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 8 // E0 JP11-10 + + #define DOGLCD_A0 40 // F2 JP2-2 + #define DOGLCD_CS 41 // F3 JP2-4 + #define LCD_SCREEN_ROT_180 + + #define BTN_EN1 2 // D2 TX1 JP2-5 + #define BTN_EN2 3 // D3 RX1 JP2-7 + #define BTN_ENC 45 // F7 TDI JP2-12 + + #define SDSS 43 // F5 TMS JP2-8 + + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 3 // D3 RX1 JP2-7 + #define BTN_EN2 2 // D2 TX1 JP2-5 + #define BTN_ENC 41 // F3 JP2-4 + #define SDSS 38 // F0 B-THERM connector - use SD card on Panelolu2 + + #else + + #define BTN_EN1 10 // C0 JP11-12 + #define BTN_EN2 11 // C1 JP11-13 + #define BTN_ENC 12 // C2 JP11-14 + + #endif + #endif // ULTRA_LCD && NEWPANEL - -#if ENABLED(VIKI2) || ENABLED(miniVIKI) - #define BEEPER_PIN 8 // E0 JP11-10 - // Pins for DOGM SPI LCD Support - #define DOGLCD_A0 40 // F2 JP2-2 - #define DOGLCD_CS 41 // F3 JP2-4 - #define LCD_SCREEN_ROT_180 - - // The encoder and click button - #define BTN_EN1 2 // D2 TX1 JP2-5 - #define BTN_EN2 3 // D3 RX1 JP2-7 - #define BTN_ENC 45 // F7 TDI JP2-12 - - #define SDSS 43 // F5 TMS JP2-8 - #define SD_DETECT_PIN -1 - - #define STAT_LED_RED_PIN 12 // C2 JP11-14 - #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 - -#endif diff --git a/Marlin/pins_PRINTRBOARD_REVF.h b/Marlin/pins_PRINTRBOARD_REVF.h index 0f1772c847..0da837fbdb 100644 --- a/Marlin/pins_PRINTRBOARD_REVF.h +++ b/Marlin/pins_PRINTRBOARD_REVF.h @@ -30,8 +30,8 @@ * There are two Arduino IDE extensions that are compatible with this board * and with the mainstream Marlin software. * - * Teensyduino - http://www.pjrc.com/teensy/teensyduino.html - * Installation instructions are at the above URL. + * Teensyduino - https://www.pjrc.com/teensy/teensyduino.html + * Installation - https://www.pjrc.com/teensy/td_download.html * * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu * @@ -66,8 +66,33 @@ #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." #endif +#ifndef USBCON + #error "USBCON should be defined by the platform for this board." +#endif + #define BOARD_NAME "Printrboard Rev F" -#define LARGE_FLASH true +// Disable JTAG pins so EXP1 pins work correctly +// (Its pins are used for the Extrudrboard and filament sensor, for example). +#define DISABLE_JTAG + +/** + * Note that REV F6 of the Printrboard stole the A HOTEND pin and + * reassigned it to a second fan for the extruder heater. It's + * recommended that you swap the A and B outputs on the Extrudrboard + * so EXTRUDERS=2 will still work on F6, using B for E1/HEATER_1/TEMP_1. + * See https://printrbot.zendesk.com/hc/en-us/articles/115003072346 + * + * If you have REV F6 you probably also want to set E0_AUTO_FAN_PIN + * to PRINTRBOARD_F6_HEATER_FAN_PIN + * + * Define NO_EXTRUDRBOARD if you don't have an EXTRUDRBOARD and wish to + * reassign different functions to EXP1. + * + * Define NO_EXTRUDRBOARD_OUTPUT_SWAP if you have a REV F5 or lower and + * want to use EXTRUDRBOARD A for E1 and EXTRUDRBOARD B for E2. + */ +//#define NO_EXTRUDRBOARD +//#define NO_EXTRUDRBOARD_OUTPUT_SWAP // // Limit Switches @@ -95,6 +120,26 @@ #define E0_DIR_PIN 35 // A7 #define E0_ENABLE_PIN 13 // C3 +#if DISABLED(NO_EXTRUDRBOARD) +#if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) + #define E1_STEP_PIN 25 // B5 + #define E1_DIR_PIN 37 // E5 + #define E1_ENABLE_PIN 42 // F4 + + #define E2_STEP_PIN 2 // D2 + #define E2_DIR_PIN 3 // D3 + #define E2_ENABLE_PIN 43 // F5 +#else + #define E1_STEP_PIN 2 // D2 + #define E1_DIR_PIN 3 // D3 + #define E1_ENABLE_PIN 43 // F5 + + #define E2_STEP_PIN 25 // B5 + #define E2_DIR_PIN 37 // E5 + #define E2_ENABLE_PIN 42 // F4 +#endif +#endif // NO_EXTRUDRBOARD + // Enable control of stepper motor currents with the I2C based MCP4728 DAC used on Printrboard REVF #define DAC_STEPPER_CURRENT @@ -119,14 +164,32 @@ #define TEMP_0_PIN 1 // Analog Input (Extruder) #define TEMP_BED_PIN 0 // Analog Input (Bed) +#if DISABLED(NO_EXTRUDRBOARD) +#if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) + #define TEMP_1_PIN 2 // Analog Input (Extrudrboard A THERM) + #define TEMP_2_PIN 3 // Analog Input (Extrudrboard B THERM) +#else + #define TEMP_1_PIN 3 // Analog Input (Extrudrboard B THERM) + #define TEMP_2_PIN 2 // Analog Input (Extrudrboard A THERM) +#endif +#endif + // // Heaters / Fans // #define HEATER_0_PIN 15 // C5 PWM3B - Extruder -#define HEATER_1_PIN 44 // F6 -#define HEATER_2_PIN 45 // F7 #define HEATER_BED_PIN 14 // C4 PWM3C +#if DISABLED(NO_EXTRUDRBOARD) +#if DISABLED(NO_EXTRUDRBOARD_OUTPUT_SWAP) + #define HEATER_1_PIN 44 // F6 - Extrudrboard A HOTEND + #define HEATER_2_PIN 45 // F7 - Extrudrboard B HOTEND +#else + #define HEATER_1_PIN 45 // F7 - Extrudrboard B HOTEND + #define HEATER_2_PIN 44 // F6 - Extrudrboard A HOTEND +#endif +#endif + #define FAN_PIN 16 // C6 PWM3A // @@ -135,8 +198,6 @@ //#define USE_INTERNAL_SD #if ENABLED(ULTRA_LCD) - #define BEEPER_PIN -1 - #define LCD_PINS_RS 9 // E1 JP11-11 #define LCD_PINS_ENABLE 8 // E0 JP11-10 #define LCD_PINS_D4 7 // D7 JP11-8 @@ -144,76 +205,73 @@ #define LCD_PINS_D6 5 // D5 JP11-6 #define LCD_PINS_D7 4 // D4 JP11-5 - #define BTN_EN1 10 // C0 JP11-12 - #define BTN_EN2 11 // C1 JP11-13 - #define BTN_ENC 12 // C2 JP11-14 + #if ENABLED(VIKI2) || ENABLED(miniVIKI) - #define SD_DETECT_PIN -1 -#endif + #define BEEPER_PIN 8 // E0 JP11-10 + #define DOGLCD_A0 40 // F2 JP2-2 + #define DOGLCD_CS 41 // F3 JP2-4 + #define LCD_SCREEN_ROT_180 -#if ENABLED(VIKI2) || ENABLED(miniVIKI) - #define BEEPER_PIN 8 // E0 JP11-10 - #define DOGLCD_A0 40 // F2 JP2-2 - #define DOGLCD_CS 41 // F3 JP2-4 - #define LCD_SCREEN_ROT_180 + #define BTN_EN1 2 // D2 TX1 JP2-5 + #define BTN_EN2 3 // D3 RX1 JP2-7 + #define BTN_ENC 45 // F7 TDI JP2-12 - #define BTN_EN1 2 // D2 TX1 JP2-5 - #define BTN_EN2 3 // D3 RX1 JP2-7 - #define BTN_ENC 45 // F7 TDI JP2-12 + #define SDSS 3 // F5 TMS JP2-8 - #define SDSS 43 // F5 TMS JP2-8 - #define SD_DETECT_PIN -1 + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 - #define STAT_LED_RED_PIN 12 // C2 JP11-14 - #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 -#endif + #elif ENABLED(MINIPANEL) + + #if DISABLED(USE_INTERNAL_SD) + // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. MKSLCD12864 PIN# + #define SDSS 11 // 36 C1 EXP2-13 EXP2-07 + #define SD_DETECT_PIN 9 // 34 E1 EXP2-11 EXP2-04 + #endif -#if ENABLED(MINIPANEL) - #if ENABLED(USE_INTERNAL_SD) - // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# - #define SDSS 20 // 10 B0 - #define SD_DETECT_PIN -1 // no auto-detect SD insertion on built-in Printrboard SD reader - #else // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. MKSLCD12864 PIN# - #define SDSS 11 // 36 C1 EXP2-13 EXP2-07 - #define SD_DETECT_PIN 9 // 34 E1 EXP2-11 EXP2-04 + #define DOGLCD_A0 4 // 29 D4 EXP2-05 EXP1-04 + #define DOGLCD_CS 5 // 30 D5 EXP2-06 EXP1-05 + #define BTN_ENC 6 // 31 D6 EXP2-07 EXP1-09 + #define BEEPER_PIN 7 // 32 D7 EXP2-08 EXP1-10 + #define KILL_PIN 8 // 33 E0 EXP2-10 EXP2-03 + #define BTN_EN1 10 // 35 C0 EXP2-12 EXP2-06 + #define BTN_EN2 12 // 37 C2 EXP2-14 EXP2-08 + //#define LCD_BACKLIGHT_PIN 43 // 56 F5 EXP1-12 Not Implemented + //#define SCK 21 // 11 B1 ICSP-04 EXP2-09 + //#define MOSI 22 // 12 B2 ICSP-03 EXP2-05 + //#define MISO 23 // 13 B3 ICSP-06 EXP2-05 + + // increase delays + #define ST7920_DELAY_1 DELAY_5_NOP + #define ST7920_DELAY_2 DELAY_5_NOP + #define ST7920_DELAY_3 DELAY_5_NOP + + #else + + #define BTN_EN1 10 // C0 JP11-12 + #define BTN_EN2 11 // C1 JP11-13 + #define BTN_ENC 12 // C2 JP11-14 + #endif - // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. MKSLCD12864 PIN# - #define DOGLCD_A0 4 // 29 D4 EXP2-05 EXP1-04 - #define DOGLCD_CS 5 // 30 D5 EXP2-06 EXP1-05 - #define BTN_ENC 6 // 31 D6 EXP2-07 EXP1-09 - #define BEEPER_PIN 7 // 32 D7 EXP2-08 EXP1-10 - #define KILL_PIN 8 // 33 E0 EXP2-10 EXP2-03 - #define BTN_EN1 10 // 35 C0 EXP2-12 EXP2-06 - #define BTN_EN2 12 // 37 C2 EXP2-14 EXP2-08 - //#define LCD_BACKLIGHT_PIN 43 // 56 F5 EXP1-12 Not Implemented - //#define SCK 21 // 11 B1 ICSP-04 EXP2-09 - //#define MOSI 22 // 12 B2 ICSP-03 EXP2-05 - //#define MISO 23 // 13 B3 ICSP-06 EXP2-05 - - // encoder connections present - #define BLEN_A 0 - #define BLEN_B 1 - #define BLEN_C 2 - - // encoder rotation values - #define encrot0 0 - #define encrot1 2 - #define encrot2 3 - #define encrot3 1 - - // increase delays to max - #define ST7920_DELAY_1 DELAY_5_NOP - #define ST7920_DELAY_2 DELAY_5_NOP - #define ST7920_DELAY_3 DELAY_5_NOP #endif // // Misc. Functions // +// PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# Printrboard RevF Conn. #ifndef SDSS - #define SDSS 20 // B0 SS + #define SDSS 20 // 10 B0 #endif -#define FILWIDTH_PIN 2 // Analog Input +/** + * This is EXP1-2, which is also the TEMP_A_PIN for the Extrudrboard. + * If using w/ Extrudrboard, cut off pin 2 on the Extrudrboard male + * connector to ensure this is disconnected from the A THERM pullups. + * You probably want to set EXTRUDERS=2 and swap the Extrudrboard outputs, + * which will let you use Channel B on the Extrudrboard as E1. + */ +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN 2 // Analog Input +#endif diff --git a/Marlin/pins_RAMBO.h b/Marlin/pins_RAMBO.h index 6ddd305eae..c6ef675bcc 100644 --- a/Marlin/pins_RAMBO.h +++ b/Marlin/pins_RAMBO.h @@ -46,8 +46,6 @@ #define BOARD_NAME "Rambo" -#define LARGE_FLASH true - // // Servos // diff --git a/Marlin/pins_RAMPS.h b/Marlin/pins_RAMPS.h index b0f66d0161..9b10751e55 100644 --- a/Marlin/pins_RAMPS.h +++ b/Marlin/pins_RAMPS.h @@ -52,8 +52,6 @@ #define BOARD_NAME "RAMPS 1.4" #endif -#define LARGE_FLASH true - // // Servos // @@ -115,6 +113,57 @@ #define E1_ENABLE_PIN 30 #define E1_CS_PIN 44 + +#if ENABLED(HAVE_TMC2208) + /** + * TMC2208 stepper drivers + * + * Hardware serial communication ports. + * If undefined software serial is used according to the pins below + */ + //#define X_HARDWARE_SERIAL Serial1 + //#define X2_HARDWARE_SERIAL Serial1 + //#define Y_HARDWARE_SERIAL Serial1 + //#define Y2_HARDWARE_SERIAL Serial1 + //#define Z_HARDWARE_SERIAL Serial1 + //#define Z2_HARDWARE_SERIAL Serial1 + //#define E0_HARDWARE_SERIAL Serial1 + //#define E1_HARDWARE_SERIAL Serial1 + //#define E2_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + //#define E3_HARDWARE_SERIAL Serial1 + + /** + * Software serial + */ + + #define X_SERIAL_TX_PIN 59 + #define X_SERIAL_RX_PIN 63 + #define X2_SERIAL_TX_PIN -1 + #define X2_SERIAL_RX_PIN -1 + + #define Y_SERIAL_TX_PIN 64 + #define Y_SERIAL_RX_PIN 40 + #define Y2_SERIAL_TX_PIN -1 + #define Y2_SERIAL_RX_PIN -1 + + #define Z_SERIAL_TX_PIN 44 + #define Z_SERIAL_RX_PIN 42 + #define Z2_SERIAL_TX_PIN -1 + #define Z2_SERIAL_RX_PIN -1 + + #define E0_SERIAL_TX_PIN 66 + #define E0_SERIAL_RX_PIN 65 + #define E1_SERIAL_TX_PIN -1 + #define E1_SERIAL_RX_PIN -1 + #define E2_SERIAL_TX_PIN -1 + #define E2_SERIAL_RX_PIN -1 + #define E3_SERIAL_TX_PIN -1 + #define E3_SERIAL_RX_PIN -1 + #define E4_SERIAL_TX_PIN -1 + #define E4_SERIAL_RX_PIN -1 +#endif + // // Temperature Sensors // @@ -285,7 +334,7 @@ #else - #if ENABLED(MKS_12864OLED) + #if ENABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306) #define LCD_PINS_DC 25 // Set as output on init #define LCD_PINS_RS 27 // Pull low for 1s to init // DOGM SPI LCD Support @@ -483,3 +532,17 @@ #endif // NEWPANEL #endif // ULTRA_LCD + +#if ENABLED(ZONESTAR_LCD) + #define LCD_PINS_RS 64 + #define LCD_PINS_ENABLE 44 + #define LCD_PINS_D4 63 + #define LCD_PINS_D5 40 + #define LCD_PINS_D6 42 + #define LCD_PINS_D7 65 + #define ADC_KEYPAD_PIN 12 + #define BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 + // pin 29 N/C +#endif // ZONESTAR_LCD diff --git a/Marlin/pins_RAMPS_PLUS.h b/Marlin/pins_RAMPS_PLUS.h new file mode 100644 index 0000000000..77e0e140c0 --- /dev/null +++ b/Marlin/pins_RAMPS_PLUS.h @@ -0,0 +1,87 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4Plus, also known as 3DYMY version, pin assignments + * The differences to the RAMPS v1.4 are: + * - Swap heater E0 with E1 + * - Swap pins 8 and 10. Bed/Fan/Hotend as labeled on the board are on pins 8/9/10. + * - Change pins 16->42, 17->44 and 29->53 used for display. + * + * Applies to the following boards: + * + * RAMPS_PLUS_EFB (Extruder, Fan, Bed) + * RAMPS_PLUS_EEB (Extruder, Extruder, Bed) + * RAMPS_PLUS_EFF (Extruder, Fan, Fan) + * RAMPS_PLUS_EEF (Extruder, Extruder, Fan) + * RAMPS_PLUS_SF (Spindle, Controller Fan) + * + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "RAMPS 1.4 Plus" +#endif + +#define RAMPS_D8_PIN 10 +#define RAMPS_D10_PIN 8 + +#include "pins_RAMPS.h" + +// +// Steppers - Swap E0 / E1 on 3DYMY +// +#undef E0_STEP_PIN +#undef E0_DIR_PIN +#undef E0_ENABLE_PIN + +#undef E1_STEP_PIN +#undef E1_DIR_PIN +#undef E1_ENABLE_PIN + +#define E0_STEP_PIN 36 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 + +#define E1_STEP_PIN 26 +#define E1_DIR_PIN 28 +#define E1_ENABLE_PIN 24 + +#undef X_CS_PIN +#undef Y_CS_PIN +#undef Z_CS_PIN +#undef E0_CS_PIN +#undef E1_CS_PIN + +#if ENABLED(ULTRA_LCD) && DISABLED(REPRAPWORLD_GRAPHICAL_LCD) && (DISABLED(NEWPANEL) || DISABLED(PANEL_ONE)) && DISABLED(CR10_STOCKDISPLAY) + #if DISABLED(MKS_12864OLED) || ENABLED(MKS_12864OLED_SSD1306) + #undef LCD_PINS_RS + #define LCD_PINS_RS 42 // 3DYMY boards pin 16 -> 42 + #undef LCD_PINS_ENABLE + #define LCD_PINS_ENABLE 44 // 3DYMY boards pin 17 -> 44 + #endif + #undef LCD_PINS_D7 + #define LCD_PINS_D7 53 // 3DYMY boards pin 29 -> 53 +#endif diff --git a/Marlin/pins_SANGUINOLOLU_11.h b/Marlin/pins_SANGUINOLOLU_11.h index 0506d78cc0..00c2c58426 100644 --- a/Marlin/pins_SANGUINOLOLU_11.h +++ b/Marlin/pins_SANGUINOLOLU_11.h @@ -59,10 +59,6 @@ #define BOARD_NAME "Sanguinololu <1.2" #endif -#ifdef __AVR_ATmega1284P__ - #define LARGE_FLASH true -#endif - // // Limit Switches // @@ -247,7 +243,21 @@ #define ST7920_DELAY_3 DELAY_0_NOP #endif - #else // !LCD_I2C_PANELOLU2 && !LCD_FOR_MELZI + #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards + + #define LCD_PINS_RS 28 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 10 + #define LCD_PINS_D5 11 + #define LCD_PINS_D6 16 + #define LCD_PINS_D7 17 + #define ADC_KEYPAD_PIN 1 + + // Not used + #define BTN_EN1 -1 + #define BTN_EN2 -1 + + #else // !LCD_I2C_PANELOLU2 && !LCD_FOR_MELZI && !ZONESTAR_LCD #define BTN_ENC 16 #define LCD_SDSS 28 // Smart Controller SD card reader rather than the Melzi diff --git a/Marlin/pins_SAV_MKI.h b/Marlin/pins_SAV_MKI.h index aecd58afde..99dd228cd2 100755 --- a/Marlin/pins_SAV_MKI.h +++ b/Marlin/pins_SAV_MKI.h @@ -69,8 +69,6 @@ #define DEFAULT_SOURCE_CODE_URL "https://github.com/fmalpartida/Marlin/tree/SAV-MkI-config" #define BOARD_NAME "SAV MkI" -#define LARGE_FLASH true - // // Servos // diff --git a/Marlin/pins_SCOOVO_X9H.h b/Marlin/pins_SCOOVO_X9H.h index 6b7cf4f800..52b8d1400b 100644 --- a/Marlin/pins_SCOOVO_X9H.h +++ b/Marlin/pins_SCOOVO_X9H.h @@ -30,8 +30,6 @@ #define BOARD_NAME "Scoovo X9H" -#define LARGE_FLASH true - // // Servos // diff --git a/Marlin/pins_SILVER_GATE.h b/Marlin/pins_SILVER_GATE.h new file mode 100644 index 0000000000..482416ee03 --- /dev/null +++ b/Marlin/pins_SILVER_GATE.h @@ -0,0 +1,92 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ + +#if !defined(__AVR_ATmega1281__) && !defined(__AVR_ATmega2561__) + #error Oops! Make sure you have 'Silvergate' selected from the 'Tools -> Boards' menu. +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Silver Gate" +#endif + +#define X_STEP_PIN 43 +#define X_DIR_PIN 44 +#define X_ENABLE_PIN 42 +#define X_MIN_PIN 31 +#define X_MAX_PIN 34 + +#define Y_STEP_PIN 40 +#define Y_DIR_PIN 41 +#define Y_ENABLE_PIN 39 +#define Y_MIN_PIN 32 +#define Y_MAX_PIN 35 + +#define Z_STEP_PIN 13 +#define Z_DIR_PIN 38 +#define Z_ENABLE_PIN 14 +#define Z_MIN_PIN 33 +#define Z_MAX_PIN 36 + +#define E0_STEP_PIN 27 +#define E0_DIR_PIN 37 +#define E0_ENABLE_PIN 45 + +#define SDSS 16 + +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN 34 // X_MAX unless overridden +#endif + +#define FAN_PIN 5 + +#define HEATER_0_PIN 7 + +#define E0_AUTO_FAN_PIN 3 +#define CONTROLLER_FAN_PIN 2 + +#define TEMP_0_PIN 7 // Analog Input + +#define HEATER_BED_PIN 8 +#define TEMP_BED_PIN 6 + +#if ENABLED(DOGLCD) + #if ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 + #define LCD_PINS_RS 30 + #define LCD_PINS_ENABLE 20 + #define LCD_PINS_D4 25 + #define BEEPER_PIN 29 + #define BTN_EN1 19 + #define BTN_EN2 22 + #define BTN_ENC 24 + #define LCD_BACKLIGHT_PIN 6 + #if ENABLED(SILVER_GATE_GLCD_CONTROLLER) + #define KILL_PIN 21 + #define HOME_PIN 28 + #endif + #endif +#endif + +#define SD_DETECT_PIN 15 + +#define STAT_LED_RED_PIN 23 +#define STAT_LED_BLUE_PIN 26 +#define CASE_LIGHT_PIN 51 diff --git a/Marlin/pins_TEENSY2.h b/Marlin/pins_TEENSY2.h index d5eb893ae7..9800eb027f 100755 --- a/Marlin/pins_TEENSY2.h +++ b/Marlin/pins_TEENSY2.h @@ -112,8 +112,6 @@ #define BOARD_NAME "Teensy++2.0" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/pins_TEENSYLU.h b/Marlin/pins_TEENSYLU.h index 0c2ded63e0..f85eee08e6 100755 --- a/Marlin/pins_TEENSYLU.h +++ b/Marlin/pins_TEENSYLU.h @@ -79,8 +79,6 @@ #define BOARD_NAME "Teensylu" -#define LARGE_FLASH true - // // Limit Switch definitions that match the SCHEMATIC diff --git a/Marlin/pins_ULTIMAKER.h b/Marlin/pins_ULTIMAKER.h index d8e7d26bf3..4549bf7fc5 100644 --- a/Marlin/pins_ULTIMAKER.h +++ b/Marlin/pins_ULTIMAKER.h @@ -40,8 +40,6 @@ #define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" #define BOARD_NAME "Ultimaker" -#define LARGE_FLASH true - // // Servos // diff --git a/Marlin/pins_ULTIMAKER_OLD.h b/Marlin/pins_ULTIMAKER_OLD.h index 5dafda2d39..e04907d981 100644 --- a/Marlin/pins_ULTIMAKER_OLD.h +++ b/Marlin/pins_ULTIMAKER_OLD.h @@ -68,8 +68,6 @@ #define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" #define BOARD_NAME "Ultimaker <1.5.4" -#define LARGE_FLASH true - // // Limit Switches // diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 74068e86fe..f83cbd4b06 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -58,6 +58,7 @@ * */ +#include "MarlinConfig.h" #include "planner.h" #include "stepper.h" #include "temperature.h" @@ -91,10 +92,20 @@ float Planner::max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second uint8_t Planner::last_extruder = 0; // Respond to extruder change #endif +int16_t Planner::flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); // Extrusion factor for each extruder + +float Planner::e_factor[EXTRUDERS]; // The flow percentage and volumetric multiplier combine to scale E movement + +#if DISABLED(NO_VOLUMETRICS) + float Planner::filament_size[EXTRUDERS], // diameter of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder + Planner::volumetric_area_nominal = CIRCLE_AREA((DEFAULT_NOMINAL_FILAMENT_DIA) * 0.5), // Nominal cross-sectional area + Planner::volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner +#endif + uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N], Planner::max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software -millis_t Planner::min_segment_time; +uint32_t Planner::min_segment_time_us; // Initialized by settings.load() float Planner::min_feedrate_mm_s, @@ -104,17 +115,31 @@ float Planner::min_feedrate_mm_s, Planner::max_jerk[XYZE], // The largest speed change requiring no acceleration Planner::min_travel_feedrate_mm_s; -#if HAS_ABL - bool Planner::abl_enabled = false; // Flag that auto bed leveling is enabled +#if HAS_LEVELING + bool Planner::leveling_active = false; // Flag that auto bed leveling is enabled + #if ABL_PLANAR + matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level + #endif + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + float Planner::z_fade_height, // Initialized by settings.load() + Planner::inverse_z_fade_height, + Planner::last_fade_z; + #endif +#else + constexpr bool Planner::leveling_active; #endif -#if ABL_PLANAR - matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level -#endif - -#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - float Planner::z_fade_height, // Initialized by settings.load() - Planner::inverse_z_fade_height; +#if ENABLED(SKEW_CORRECTION) + #if ENABLED(SKEW_CORRECTION_GCODE) + float Planner::xy_skew_factor; + #else + constexpr float Planner::xy_skew_factor; + #endif + #if ENABLED(SKEW_CORRECTION_FOR_Z) && ENABLED(SKEW_CORRECTION_GCODE) + float Planner::xz_skew_factor, Planner::yz_skew_factor; + #else + constexpr float Planner::xz_skew_factor, Planner::yz_skew_factor; + #endif #endif #if ENABLED(AUTOTEMP) @@ -126,7 +151,7 @@ float Planner::min_feedrate_mm_s, // private: -long Planner::position[NUM_AXIS] = { 0 }; +int32_t Planner::position[NUM_AXIS] = { 0 }; uint32_t Planner::cutoff_long; @@ -141,13 +166,15 @@ float Planner::previous_speed[NUM_AXIS], // Old direction bits. Used for speed calculations unsigned char Planner::old_direction_bits = 0; // Segment times (in µs). Used for speed calculations - long Planner::axis_segment_time[2][3] = { {MAX_FREQ_TIME + 1, 0, 0}, {MAX_FREQ_TIME + 1, 0, 0} }; + uint32_t Planner::axis_segment_time_us[2][3] = { { MAX_FREQ_TIME_US + 1, 0, 0 }, { MAX_FREQ_TIME_US + 1, 0, 0 } }; #endif #if ENABLED(LIN_ADVANCE) float Planner::extruder_advance_k, // Initialized by settings.load() Planner::advance_ed_ratio, // Initialized by settings.load() - Planner::position_float[NUM_AXIS] = { 0 }; + Planner::position_float[XYZE], // Needed for accurate maths. Steps cannot be used! + Planner::lin_dist_xy, + Planner::lin_dist_e; #endif #if ENABLED(ULTRA_LCD) @@ -187,14 +214,18 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e NOLESS(initial_rate, MINIMAL_STEP_RATE); NOLESS(final_rate, MINIMAL_STEP_RATE); - int32_t accel = block->acceleration_steps_per_s2, - accelerate_steps = CEIL(estimate_acceleration_distance(initial_rate, block->nominal_rate, accel)), + const int32_t accel = block->acceleration_steps_per_s2; + + // Steps required for acceleration, deceleration to/from nominal rate + int32_t accelerate_steps = CEIL(estimate_acceleration_distance(initial_rate, block->nominal_rate, accel)), decelerate_steps = FLOOR(estimate_acceleration_distance(block->nominal_rate, final_rate, -accel)), + // Steps between acceleration and deceleration, if any plateau_steps = block->step_event_count - accelerate_steps - decelerate_steps; - // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will - // have to use intersection_distance() to calculate when to abort accel and start braking - // in order to reach the final_rate exactly at the end of this block. + // Does accelerate_steps + decelerate_steps exceed step_event_count? + // Then we can't possibly reach the nominal rate, there will be no cruising. + // Use intersection_distance() to calculate accel / braking time in order to + // reach the final_rate exactly at the end of this block. if (plateau_steps < 0) { accelerate_steps = CEIL(intersection_distance(initial_rate, final_rate, accel, block->step_event_count)); NOLESS(accelerate_steps, 0); // Check limits due to numerical round-off @@ -225,7 +256,7 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e // The kernel called by recalculate() when scanning the plan from last to first entry. -void Planner::reverse_pass_kernel(block_t* const current, const block_t *next) { +void Planner::reverse_pass_kernel(block_t* const current, const block_t * const next) { if (!current || !next) return; // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and @@ -246,31 +277,25 @@ void Planner::reverse_pass_kernel(block_t* const current, const block_t *next) { * Once in reverse and once forward. This implements the reverse pass. */ void Planner::reverse_pass() { - if (movesplanned() > 3) { + const uint8_t endnr = BLOCK_MOD(block_buffer_tail + 2); // tail is running. tail+1 shouldn't be altered because it's connected to the running block. + // tail+2 because the index is not yet advanced when checked + uint8_t blocknr = prev_block_index(block_buffer_head); + block_t* current = &block_buffer[blocknr]; - block_t* block[3] = { NULL, NULL, NULL }; - - // Make a local copy of block_buffer_tail, because the interrupt can alter it - // Is a critical section REALLY needed for a single byte change? - //CRITICAL_SECTION_START; - uint8_t tail = block_buffer_tail; - //CRITICAL_SECTION_END - - uint8_t b = BLOCK_MOD(block_buffer_head - 3); - while (b != tail) { - if (block[0] && TEST(block[0]->flag, BLOCK_BIT_START_FROM_FULL_HALT)) break; - b = prev_block_index(b); - block[2] = block[1]; - block[1] = block[0]; - block[0] = &block_buffer[b]; - reverse_pass_kernel(block[1], block[2]); - } + do { + const block_t * const next = current; + blocknr = prev_block_index(blocknr); + current = &block_buffer[blocknr]; + if (TEST(current->flag, BLOCK_BIT_START_FROM_FULL_HALT)) // Up to this every block is already optimized. + break; + reverse_pass_kernel(current, next); + } while (blocknr != endnr); } } // The kernel called by recalculate() when scanning the plan from first to last entry. -void Planner::forward_pass_kernel(const block_t* previous, block_t* const current) { +void Planner::forward_pass_kernel(const block_t * const previous, block_t* const current) { if (!previous) return; // If the previous block is an acceleration block, but it is not long enough to complete the @@ -322,8 +347,8 @@ void Planner::recalculate_trapezoids() { // Recalculate if current block entry or exit junction speed has changed. if (TEST(current->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE)) { // NOTE: Entry and exit factors always > 0 by all previous logic operations. - float nom = current->nominal_speed; - calculate_trapezoid_for_block(current, current->entry_speed / nom, next->entry_speed / nom); + const float nomr = 1.0 / current->nominal_speed; + calculate_trapezoid_for_block(current, current->entry_speed * nomr, next->entry_speed * nomr); CBI(current->flag, BLOCK_BIT_RECALCULATE); // Reset current only to ensure next trapezoid is computed } } @@ -331,8 +356,8 @@ void Planner::recalculate_trapezoids() { } // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. if (next) { - float nom = next->nominal_speed; - calculate_trapezoid_for_block(next, next->entry_speed / nom, (MINIMUM_PLANNER_SPEED) / nom); + const float nomr = 1.0 / next->nominal_speed; + calculate_trapezoid_for_block(next, next->entry_speed * nomr, (MINIMUM_PLANNER_SPEED) * nomr); CBI(next->flag, BLOCK_BIT_RECALCULATE); } } @@ -401,23 +426,20 @@ void Planner::check_axes_activity() { unsigned char axis_active[NUM_AXIS] = { 0 }, tail_fan_speed[FAN_COUNT]; - #if FAN_COUNT > 0 - for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = fanSpeeds[i]; - #endif - #if ENABLED(BARICUDA) #if HAS_HEATER_1 - uint8_t tail_valve_pressure = baricuda_valve_pressure; + uint8_t tail_valve_pressure; #endif #if HAS_HEATER_2 - uint8_t tail_e_to_p_pressure = baricuda_e_to_p_pressure; + uint8_t tail_e_to_p_pressure; #endif #endif if (blocks_queued()) { #if FAN_COUNT > 0 - for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = block_buffer[block_buffer_tail].fan_speed[i]; + for (uint8_t i = 0; i < FAN_COUNT; i++) + tail_fan_speed[i] = block_buffer[block_buffer_tail].fan_speed[i]; #endif block_t* block; @@ -437,6 +459,21 @@ void Planner::check_axes_activity() { LOOP_XYZE(i) if (block->steps[i]) axis_active[i]++; } } + else { + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = fanSpeeds[i]; + #endif + + #if ENABLED(BARICUDA) + #if HAS_HEATER_1 + tail_valve_pressure = baricuda_valve_pressure; + #endif + #if HAS_HEATER_2 + tail_e_to_p_pressure = baricuda_e_to_p_pressure; + #endif + #endif + } + #if ENABLED(DISABLE_X) if (!axis_active[X_AXIS]) disable_X(); #endif @@ -452,13 +489,7 @@ void Planner::check_axes_activity() { #if FAN_COUNT > 0 - #ifdef FAN_MIN_PWM - #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0) - #else - #define CALC_FAN_SPEED(f) tail_fan_speed[f] - #endif - - #ifdef FAN_KICKSTART_TIME + #if FAN_KICKSTART_TIME > 0 static millis_t fan_kick_end[FAN_COUNT] = { 0 }; @@ -482,7 +513,13 @@ void Planner::check_axes_activity() { KICKSTART_FAN(2); #endif - #endif // FAN_KICKSTART_TIME + #endif // FAN_KICKSTART_TIME > 0 + + #ifdef FAN_MIN_PWM + #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0) + #else + #define CALC_FAN_SPEED(f) tail_fan_speed[f] + #endif #if ENABLED(FAN_SOFT_PWM) #if HAS_FAN0 @@ -522,260 +559,206 @@ void Planner::check_axes_activity() { #endif } +#if DISABLED(NO_VOLUMETRICS) + + /** + * Get a volumetric multiplier from a filament diameter. + * This is the reciprocal of the circular cross-section area. + * Return 1.0 with volumetric off or a diameter of 0.0. + */ + inline float calculate_volumetric_multiplier(const float &diameter) { + return (parser.volumetric_enabled && diameter) ? 1.0 / CIRCLE_AREA(diameter * 0.5) : 1.0; + } + + /** + * Convert the filament sizes into volumetric multipliers. + * The multiplier converts a given E value into a length. + */ + void Planner::calculate_volumetric_multipliers() { + for (uint8_t i = 0; i < COUNT(filament_size); i++) { + volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); + refresh_e_factor(i); + } + } + +#endif // !NO_VOLUMETRICS + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + /** + * Convert the ratio value given by the filament width sensor + * into a volumetric multiplier. Conversion differs when using + * linear extrusion vs volumetric extrusion. + */ + void Planner::calculate_volumetric_for_width_sensor(const int8_t encoded_ratio) { + // Reconstitute the nominal/measured ratio + const float nom_meas_ratio = 1.0 + 0.01 * encoded_ratio, + ratio_2 = sq(nom_meas_ratio); + + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = parser.volumetric_enabled + ? ratio_2 / CIRCLE_AREA(filament_width_nominal * 0.5) // Volumetric uses a true volumetric multiplier + : ratio_2; // Linear squares the ratio, which scales the volume + + refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM); + } +#endif + #if PLANNER_LEVELING /** - * lx, ly, lz - logical (cartesian, not delta) positions in mm + * rx, ry, rz - Cartesian positions in mm + * Leveled XYZ on completion */ - void Planner::apply_leveling(float &lx, float &ly, float &lz) { + void Planner::apply_leveling(float &rx, float &ry, float &rz) { + + #if ENABLED(SKEW_CORRECTION) + skew(rx, ry, rz); + #endif + + if (!leveling_active) return; + + #if ABL_PLANAR + + float dx = rx - (X_TILT_FULCRUM), + dy = ry - (Y_TILT_FULCRUM); + + apply_rotation_xyz(bed_level_matrix, dx, dy, rz); + + rx = dx + X_TILT_FULCRUM; + ry = dy + Y_TILT_FULCRUM; + + #else - #if ENABLED(AUTO_BED_LEVELING_UBL) - if (!ubl.state.active) return; #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - // if z_fade_height enabled (nonzero) and raw_z above it, no leveling required - if (planner.z_fade_height && planner.z_fade_height <= RAW_Z_POSITION(lz)) return; - lz += ubl.state.z_offset + ubl.get_z_correction(lx, ly) * ubl.fade_scaling_factor_for_z(lz); - #else // no fade - lz += ubl.state.z_offset + ubl.get_z_correction(lx, ly); - #endif // FADE - #endif // UBL + const float fade_scaling_factor = fade_scaling_factor_for_z(rz); + if (!fade_scaling_factor) return; + #elif HAS_MESH + constexpr float fade_scaling_factor = 1.0; + #endif - #if HAS_ABL - if (!abl_enabled) return; - #endif + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + const float raw[XYZ] = { rx, ry, 0 }; + #endif - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_UBL) - static float z_fade_factor = 1.0, last_raw_lz = -999.0; - if (z_fade_height) { - const float raw_lz = RAW_Z_POSITION(lz); - if (raw_lz >= z_fade_height) return; - if (last_raw_lz != raw_lz) { - last_raw_lz = raw_lz; - z_fade_factor = 1.0 - raw_lz * inverse_z_fade_height; - } - } - else - z_fade_factor = 1.0; - #endif - - #if ENABLED(MESH_BED_LEVELING) - - if (mbl.active()) - lz += mbl.get_z(RAW_X_POSITION(lx), RAW_Y_POSITION(ly) - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - , z_fade_factor - #endif - ); - - #elif ABL_PLANAR - - float dx = RAW_X_POSITION(lx) - (X_TILT_FULCRUM), - dy = RAW_Y_POSITION(ly) - (Y_TILT_FULCRUM), - dz = RAW_Z_POSITION(lz); - - apply_rotation_xyz(bed_level_matrix, dx, dy, dz); - - lx = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); - ly = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); - lz = LOGICAL_Z_POSITION(dz); - - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - - float tmp[XYZ] = { lx, ly, 0 }; - lz += bilinear_z_offset(tmp) - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - * z_fade_factor + rz += ( + #if ENABLED(AUTO_BED_LEVELING_UBL) + ubl.get_z_correction(rx, ry) * fade_scaling_factor + #elif ENABLED(MESH_BED_LEVELING) + mbl.get_z(rx, ry + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + , fade_scaling_factor + #endif + ) + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + bilinear_z_offset(raw) * fade_scaling_factor + #else + 0 #endif - ; + ); #endif } - void Planner::unapply_leveling(float logical[XYZ]) { - - #if ENABLED(AUTO_BED_LEVELING_UBL) - - if (ubl.state.active) { - - const float z_physical = RAW_Z_POSITION(logical[Z_AXIS]), - z_correct = ubl.get_z_correction(logical[X_AXIS], logical[Y_AXIS]), - z_virtual = z_physical - ubl.state.z_offset - z_correct; - float z_logical = LOGICAL_Z_POSITION(z_virtual); - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - - // for P=physical_z, L=logical_z, M=mesh_z, O=z_offset, H=fade_height, - // Given P=L+O+M(1-L/H) (faded mesh correction formula for L= planner.z_fade_height) - z_logical = LOGICAL_Z_POSITION(z_physical - ubl.state.z_offset); - else - z_logical /= 1.0 - z_correct * planner.inverse_z_fade_height; - } - - #endif // ENABLE_LEVELING_FADE_HEIGHT - - logical[Z_AXIS] = z_logical; - } - - return; // don't fall thru to other ENABLE_LEVELING_FADE_HEIGHT logic - - #endif - - #if HAS_ABL - if (!abl_enabled) return; - #endif + void Planner::unapply_leveling(float raw[XYZ]) { #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (z_fade_height && RAW_Z_POSITION(logical[Z_AXIS]) >= z_fade_height) return; + const float fade_scaling_factor = fade_scaling_factor_for_z(raw[Z_AXIS]); + #else + constexpr float fade_scaling_factor = 1.0; #endif - #if ENABLED(MESH_BED_LEVELING) + if (leveling_active && fade_scaling_factor) { - if (mbl.active()) { - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - const float c = mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS]), 1.0); - logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); - #else - logical[Z_AXIS] -= mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS])); - #endif - } + #if ABL_PLANAR - #elif ABL_PLANAR + matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); - matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); + float dx = raw[X_AXIS] - (X_TILT_FULCRUM), + dy = raw[Y_AXIS] - (Y_TILT_FULCRUM); - float dx = RAW_X_POSITION(logical[X_AXIS]) - (X_TILT_FULCRUM), - dy = RAW_Y_POSITION(logical[Y_AXIS]) - (Y_TILT_FULCRUM), - dz = RAW_Z_POSITION(logical[Z_AXIS]); + apply_rotation_xyz(inverse, dx, dy, raw[Z_AXIS]); - apply_rotation_xyz(inverse, dx, dy, dz); + raw[X_AXIS] = dx + X_TILT_FULCRUM; + raw[Y_AXIS] = dy + Y_TILT_FULCRUM; - logical[X_AXIS] = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); - logical[Y_AXIS] = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); - logical[Z_AXIS] = LOGICAL_Z_POSITION(dz); + #else // !ABL_PLANAR - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + raw[Z_AXIS] -= ( + #if ENABLED(AUTO_BED_LEVELING_UBL) + ubl.get_z_correction(raw[X_AXIS], raw[Y_AXIS]) * fade_scaling_factor + #elif ENABLED(MESH_BED_LEVELING) + mbl.get_z(raw[X_AXIS], raw[Y_AXIS] + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + , fade_scaling_factor + #endif + ) + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + bilinear_z_offset(raw) * fade_scaling_factor + #else + 0 + #endif + ); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - const float c = bilinear_z_offset(logical); - logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); - #else - logical[Z_AXIS] -= bilinear_z_offset(logical); - #endif + #endif // !ABL_PLANAR + } + #if ENABLED(SKEW_CORRECTION) + unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); #endif } #endif // PLANNER_LEVELING /** - * Planner::_buffer_line + * Planner::_buffer_steps * - * Add a new linear movement to the buffer. + * Add a new linear movement to the buffer (in terms of steps). * - * Leveling and kinematics should be applied ahead of calling this. - * - * a,b,c,e - target positions in mm or degrees + * target - target position in steps units * fr_mm_s - (target) speed of the move * extruder - target extruder */ -void Planner::_buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder) { +void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const uint8_t extruder) { - // The target position of the tool in absolute steps - // Calculate target position in absolute steps - //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow - const long target[XYZE] = { - LROUND(a * axis_steps_per_mm[X_AXIS]), - LROUND(b * axis_steps_per_mm[Y_AXIS]), - LROUND(c * axis_steps_per_mm[Z_AXIS]), - LROUND(e * axis_steps_per_mm[E_AXIS_N]) - }; + const int32_t da = target[X_AXIS] - position[X_AXIS], + db = target[Y_AXIS] - position[Y_AXIS], + dc = target[Z_AXIS] - position[Z_AXIS]; - // When changing extruders recalculate steps corresponding to the E position - #if ENABLED(DISTINCT_E_FACTORS) - if (last_extruder != extruder && axis_steps_per_mm[E_AXIS_N] != axis_steps_per_mm[E_AXIS + last_extruder]) { - position[E_AXIS] = LROUND(position[E_AXIS] * axis_steps_per_mm[E_AXIS_N] * steps_to_mm[E_AXIS + last_extruder]); - last_extruder = extruder; - } - #endif + int32_t de = target[E_AXIS] - position[E_AXIS]; - #if ENABLED(LIN_ADVANCE) - const float mm_D_float = SQRT(sq(a - position_float[X_AXIS]) + sq(b - position_float[Y_AXIS])); - #endif - - const long da = target[X_AXIS] - position[X_AXIS], - db = target[Y_AXIS] - position[Y_AXIS], - dc = target[Z_AXIS] - position[Z_AXIS]; - - /* - SERIAL_ECHOPAIR(" Planner FR:", fr_mm_s); - SERIAL_CHAR(' '); - #if IS_KINEMATIC - SERIAL_ECHOPAIR("A:", a); + /* <-- add a slash to enable + SERIAL_ECHOPAIR(" _buffer_steps FR:", fr_mm_s); + SERIAL_ECHOPAIR(" A:", target[A_AXIS]); SERIAL_ECHOPAIR(" (", da); - SERIAL_ECHOPAIR(") B:", b); - #else - SERIAL_ECHOPAIR("X:", a); - SERIAL_ECHOPAIR(" (", da); - SERIAL_ECHOPAIR(") Y:", b); - #endif - SERIAL_ECHOPAIR(" (", db); - #if ENABLED(DELTA) - SERIAL_ECHOPAIR(") C:", c); - #else - SERIAL_ECHOPAIR(") Z:", c); - #endif - SERIAL_ECHOPAIR(" (", dc); - SERIAL_CHAR(')'); - SERIAL_EOL(); + SERIAL_ECHOPAIR(" steps) B:", target[B_AXIS]); + SERIAL_ECHOPAIR(" (", db); + SERIAL_ECHOPAIR(" steps) C:", target[C_AXIS]); + SERIAL_ECHOPAIR(" (", dc); + SERIAL_ECHOPAIR(" steps) E:", target[E_AXIS]); + SERIAL_ECHOPAIR(" (", de); + SERIAL_ECHOLNPGM(" steps)"); //*/ - // DRYRUN ignores all temperature constraints and assures that the extruder is instantly satisfied - if (DEBUGGING(DRYRUN)) { - position[E_AXIS] = target[E_AXIS]; - #if ENABLED(LIN_ADVANCE) - position_float[E_AXIS] = e; - #endif - } - - long de = target[E_AXIS] - position[E_AXIS]; - - #if ENABLED(LIN_ADVANCE) - float de_float = e - position_float[E_AXIS]; - #endif - - #if ENABLED(PREVENT_COLD_EXTRUSION) + // If LIN_ADVANCE is disabled then do E move prevention with integers + // Otherwise it's done in _buffer_segment. + #if DISABLED(LIN_ADVANCE) && (ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)) if (de) { - if (thermalManager.tooColdToExtrude(extruder)) { - position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part - de = 0; // no difference - #if ENABLED(LIN_ADVANCE) - position_float[E_AXIS] = e; - de_float = 0; - #endif - SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); - } - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (labs(de) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.tooColdToExtrude(extruder)) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #endif // PREVENT_COLD_EXTRUSION + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (labs(de * e_factor[extruder]) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part de = 0; // no difference - #if ENABLED(LIN_ADVANCE) - position_float[E_AXIS] = e; - de_float = 0; - #endif SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); } - #endif + #endif // PREVENT_LENGTHY_EXTRUDE } - #endif + #endif // !LIN_ADVANCE && (PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE) // Compute direction bit-mask for this block uint8_t dm = 0; @@ -804,7 +787,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const #endif if (de < 0) SBI(dm, E_AXIS); - const float esteps_float = de * volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01; + const float esteps_float = de * e_factor[extruder]; const int32_t esteps = abs(esteps_float) + 0.5; // Calculate the buffer head after we push this byte @@ -818,7 +801,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const block_t* block = &block_buffer[block_buffer_head]; // Clear all flags, including the "busy" bit - block->flag = 0; + block->flag = 0x00; // Set direction bits block->direction_bits = dm; @@ -1049,25 +1032,28 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const #endif ); } - float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides + const float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides - // Calculate moves/second for this move. No divide by zero due to previous checks. - float inverse_mm_s = fr_mm_s * inverse_millimeters; + // Calculate inverse time for this move. No divide by zero due to previous checks. + // Example: At 120mm/s a 60mm move takes 0.5s. So this will give 2.0. + float inverse_secs = fr_mm_s * inverse_millimeters; const uint8_t moves_queued = movesplanned(); // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill #if ENABLED(SLOWDOWN) || ENABLED(ULTRA_LCD) || defined(XY_FREQUENCY_LIMIT) // Segment time im micro seconds - unsigned long segment_time = LROUND(1000000.0 / inverse_mm_s); + uint32_t segment_time_us = LROUND(1000000.0 / inverse_secs); #endif + #if ENABLED(SLOWDOWN) if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / 2 - 1)) { - if (segment_time < min_segment_time) { + if (segment_time_us < min_segment_time_us) { // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. - inverse_mm_s = 1000000.0 / (segment_time + LROUND(2 * (min_segment_time - segment_time) / moves_queued)); + const uint32_t nst = segment_time_us + LROUND(2 * (min_segment_time_us - segment_time_us) / moves_queued); + inverse_secs = 1000000.0 / nst; #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ULTRA_LCD) - segment_time = LROUND(1000000.0 / inverse_mm_s); + segment_time_us = nst; #endif } } @@ -1075,12 +1061,12 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const #if ENABLED(ULTRA_LCD) CRITICAL_SECTION_START - block_buffer_runtime_us += segment_time; + block_buffer_runtime_us += segment_time_us; CRITICAL_SECTION_END #endif - block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0 - block->nominal_rate = CEIL(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0 + block->nominal_speed = block->millimeters * inverse_secs; // (mm/sec) Always > 0 + block->nominal_rate = CEIL(block->step_event_count * inverse_secs); // (step/sec) Always > 0 #if ENABLED(FILAMENT_WIDTH_SENSOR) static float filwidth_e_count = 0, filwidth_delay_dist = 0; @@ -1088,14 +1074,14 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const //FMM update ring buffer used for delay with filament measurements if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM && filwidth_delay_index[1] >= 0) { //only for extruder with filament sensor and if ring buffer is initialized - const int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10; + constexpr int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10; // increment counters with next move in e axis filwidth_e_count += delta_mm[E_AXIS]; filwidth_delay_dist += delta_mm[E_AXIS]; // Only get new measurements on forward E movement - if (filwidth_e_count > 0.0001) { + if (!UNEAR_ZERO(filwidth_e_count)) { // Loop the delay distance counter (modulus by the mm length) while (filwidth_delay_dist >= MMD_MM) filwidth_delay_dist -= MMD_MM; @@ -1106,7 +1092,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const // If the index has changed (must have gone forward)... if (filwidth_delay_index[0] != filwidth_delay_index[1]) { filwidth_e_count = 0; // Reset the E movement counter - const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char + const int8_t meas_sample = thermalManager.widthFil_to_size_ratio(); do { filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot measurement_delay[filwidth_delay_index[1]] = meas_sample; // Store the measurement @@ -1119,7 +1105,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const // Calculate and limit speed in mm/sec for each axis float current_speed[NUM_AXIS], speed_factor = 1.0; // factor <1 decreases speed LOOP_XYZE(i) { - const float cs = FABS(current_speed[i] = delta_mm[i] * inverse_mm_s); + const float cs = FABS((current_speed[i] = delta_mm[i] * inverse_secs)); #if ENABLED(DISTINCT_E_FACTORS) if (i == E_AXIS) i += extruder; #endif @@ -1132,34 +1118,34 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const // Check and limit the xy direction change frequency const unsigned char direction_change = block->direction_bits ^ old_direction_bits; old_direction_bits = block->direction_bits; - segment_time = LROUND((float)segment_time / speed_factor); + segment_time_us = LROUND((float)segment_time_us / speed_factor); - long xs0 = axis_segment_time[X_AXIS][0], - xs1 = axis_segment_time[X_AXIS][1], - xs2 = axis_segment_time[X_AXIS][2], - ys0 = axis_segment_time[Y_AXIS][0], - ys1 = axis_segment_time[Y_AXIS][1], - ys2 = axis_segment_time[Y_AXIS][2]; + uint32_t xs0 = axis_segment_time_us[X_AXIS][0], + xs1 = axis_segment_time_us[X_AXIS][1], + xs2 = axis_segment_time_us[X_AXIS][2], + ys0 = axis_segment_time_us[Y_AXIS][0], + ys1 = axis_segment_time_us[Y_AXIS][1], + ys2 = axis_segment_time_us[Y_AXIS][2]; if (TEST(direction_change, X_AXIS)) { - xs2 = axis_segment_time[X_AXIS][2] = xs1; - xs1 = axis_segment_time[X_AXIS][1] = xs0; + xs2 = axis_segment_time_us[X_AXIS][2] = xs1; + xs1 = axis_segment_time_us[X_AXIS][1] = xs0; xs0 = 0; } - xs0 = axis_segment_time[X_AXIS][0] = xs0 + segment_time; + xs0 = axis_segment_time_us[X_AXIS][0] = xs0 + segment_time_us; if (TEST(direction_change, Y_AXIS)) { - ys2 = axis_segment_time[Y_AXIS][2] = axis_segment_time[Y_AXIS][1]; - ys1 = axis_segment_time[Y_AXIS][1] = axis_segment_time[Y_AXIS][0]; + ys2 = axis_segment_time_us[Y_AXIS][2] = axis_segment_time_us[Y_AXIS][1]; + ys1 = axis_segment_time_us[Y_AXIS][1] = axis_segment_time_us[Y_AXIS][0]; ys0 = 0; } - ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time; + ys0 = axis_segment_time_us[Y_AXIS][0] = ys0 + segment_time_us; - const long max_x_segment_time = MAX3(xs0, xs1, xs2), - max_y_segment_time = MAX3(ys0, ys1, ys2), - min_xy_segment_time = min(max_x_segment_time, max_y_segment_time); - if (min_xy_segment_time < MAX_FREQ_TIME) { - const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME); + const uint32_t max_x_segment_time = MAX3(xs0, xs1, xs2), + max_y_segment_time = MAX3(ys0, ys1, ys2), + min_xy_segment_time = min(max_x_segment_time, max_y_segment_time); + if (min_xy_segment_time < MAX_FREQ_TIME_US) { + const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME_US); NOMORE(speed_factor, low_sf); } #endif // XY_FREQUENCY_LIMIT @@ -1253,12 +1239,12 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles. - if (block_buffer_head != block_buffer_tail && previous_nominal_speed > 0.0) { + if (moves_queued && !UNEAR_ZERO(previous_nominal_speed)) { // Compute cosine of angle between previous and current path. (prev_unit_vec is negative) // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity. - float cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] - - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] - - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ; + const float cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] + - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] + - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS]; // Skip and use default max junction speed for 0 degree acute junction. if (cos_theta < 0.95) { vmax_junction = min(previous_nominal_speed, block->nominal_speed); @@ -1298,24 +1284,25 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const } } - if (moves_queued > 1 && previous_nominal_speed > 0.0001) { + if (moves_queued && !UNEAR_ZERO(previous_nominal_speed)) { // Estimate a maximum velocity allowed at a joint of two successive segments. // If this maximum velocity allowed is lower than the minimum of the entry / exit safe velocities, // then the machine is not coasting anymore and the safe entry / exit velocities shall be used. // The junction velocity will be shared between successive segments. Limit the junction velocity to their minimum. - bool prev_speed_larger = previous_nominal_speed > block->nominal_speed; - float smaller_speed_factor = prev_speed_larger ? (block->nominal_speed / previous_nominal_speed) : (previous_nominal_speed / block->nominal_speed); // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. - vmax_junction = prev_speed_larger ? block->nominal_speed : previous_nominal_speed; + vmax_junction = min(block->nominal_speed, previous_nominal_speed); + // Factor to multiply the previous / current nominal velocities to get componentwise limited velocities. - float v_factor = 1.f; + float v_factor = 1; limited = 0; + // Now limit the jerk in all axes. + const float smaller_speed_factor = vmax_junction / previous_nominal_speed; LOOP_XYZE(axis) { // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop. - float v_exit = previous_speed[axis], v_entry = current_speed[axis]; - if (prev_speed_larger) v_exit *= smaller_speed_factor; + float v_exit = previous_speed[axis] * smaller_speed_factor, + v_entry = current_speed[axis]; if (limited) { v_exit *= v_factor; v_entry *= v_factor; @@ -1324,9 +1311,9 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const // Calculate jerk depending on whether the axis is coasting in the same direction or reversing. const float jerk = (v_exit > v_entry) ? // coasting axis reversal - ( (v_entry > 0.f || v_exit < 0.f) ? (v_exit - v_entry) : max(v_exit, -v_entry) ) + ( (v_entry > 0 || v_exit < 0) ? (v_exit - v_entry) : max(v_exit, -v_entry) ) : // v_exit <= v_entry coasting axis reversal - ( (v_entry < 0.f || v_exit > 0.f) ? (v_entry - v_exit) : max(-v_exit, v_entry) ); + ( (v_entry < 0 || v_exit > 0) ? (v_entry - v_exit) : max(-v_exit, v_entry) ); if (jerk > max_jerk[axis]) { v_factor *= max_jerk[axis] / jerk; @@ -1372,56 +1359,185 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const previous_safe_speed = safe_speed; #if ENABLED(LIN_ADVANCE) - - // - // Use LIN_ADVANCE for blocks if all these are true: - // - // esteps : We have E steps todo (a printing move) - // - // block->steps[X_AXIS] || block->steps[Y_AXIS] : We have a movement in XY direction (i.e., not retract / prime). - // - // extruder_advance_k : There is an advance factor set. - // - // block->steps[E_AXIS] != block->step_event_count : A problem occurs if the move before a retract is too small. - // In that case, the retract and move will be executed together. - // This leads to too many advance steps due to a huge e_acceleration. - // The math is good, but we must avoid retract moves with advance! - // de_float > 0.0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) - // - block->use_advance_lead = esteps - && (block->steps[X_AXIS] || block->steps[Y_AXIS]) + /** + * + * Use LIN_ADVANCE for blocks if all these are true: + * + * esteps && (block->steps[X_AXIS] || block->steps[Y_AXIS]) : This is a print move + * + * extruder_advance_k : There is an advance factor set. + * + * esteps != block->step_event_count : A problem occurs if the move before a retract is too small. + * In that case, the retract and move will be executed together. + * This leads to too many advance steps due to a huge e_acceleration. + * The math is good, but we must avoid retract moves with advance! + * lin_dist_e > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) + */ + block->use_advance_lead = esteps && (block->steps[X_AXIS] || block->steps[Y_AXIS]) && extruder_advance_k && (uint32_t)esteps != block->step_event_count - && de_float > 0.0; + && lin_dist_e > 0; if (block->use_advance_lead) block->abs_adv_steps_multiplier8 = LROUND( extruder_advance_k - * (UNEAR_ZERO(advance_ed_ratio) ? de_float / mm_D_float : advance_ed_ratio) // Use the fixed ratio, if set + * (UNEAR_ZERO(advance_ed_ratio) ? lin_dist_e / lin_dist_xy : advance_ed_ratio) // Use the fixed ratio, if set * (block->nominal_speed / (float)block->nominal_rate) * axis_steps_per_mm[E_AXIS_N] * 256.0 ); #endif // LIN_ADVANCE - calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed); + const float bnsr = 1.0 / block->nominal_speed; + calculate_trapezoid_for_block(block, block->entry_speed * bnsr, safe_speed * bnsr); // Move buffer head block_buffer_head = next_buffer_head; // Update the position (only when a move was queued) + static_assert(COUNT(target) > 1, "Parameter to _buffer_steps must be (&target)[XYZE]!"); COPY(position, target); - #if ENABLED(LIN_ADVANCE) - position_float[X_AXIS] = a; - position_float[Y_AXIS] = b; - position_float[Z_AXIS] = c; - position_float[E_AXIS] = e; - #endif recalculate(); +} // _buffer_steps() + +/** + * Planner::buffer_segment + * + * Add a new linear movement to the buffer in axis units. + * + * Leveling and kinematics should be applied ahead of calling this. + * + * a,b,c,e - target positions in mm and/or degrees + * fr_mm_s - (target) speed of the move + * extruder - target extruder + */ +void Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder) { + // When changing extruders recalculate steps corresponding to the E position + #if ENABLED(DISTINCT_E_FACTORS) + if (last_extruder != extruder && axis_steps_per_mm[E_AXIS_N] != axis_steps_per_mm[E_AXIS + last_extruder]) { + position[E_AXIS] = LROUND(position[E_AXIS] * axis_steps_per_mm[E_AXIS_N] * steps_to_mm[E_AXIS + last_extruder]); + last_extruder = extruder; + } + #endif + + // The target position of the tool in absolute steps + // Calculate target position in absolute steps + const int32_t target[XYZE] = { + LROUND(a * axis_steps_per_mm[X_AXIS]), + LROUND(b * axis_steps_per_mm[Y_AXIS]), + LROUND(c * axis_steps_per_mm[Z_AXIS]), + LROUND(e * axis_steps_per_mm[E_AXIS_N]) + }; + + // DRYRUN prevents E moves from taking place + if (DEBUGGING(DRYRUN)) { + position[E_AXIS] = target[E_AXIS]; + #if ENABLED(LIN_ADVANCE) + position_float[E_AXIS] = e; + #endif + } + + #if ENABLED(LIN_ADVANCE) + lin_dist_e = e - position_float[E_AXIS]; + #endif + + // If LIN_ADVANCE is enabled then do E move prevention with floats + // Otherwise it's done in _buffer_steps. + #if ENABLED(LIN_ADVANCE) && (ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE)) + if (lin_dist_e) { + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.tooColdToExtrude(extruder)) { + position_float[E_AXIS] = e; // Behave as if the move really took place, but ignore E part + position[E_AXIS] = target[E_AXIS]; + lin_dist_e = 0; + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #endif // PREVENT_COLD_EXTRUSION + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (lin_dist_e * e_factor[extruder] > (EXTRUDE_MAXLENGTH)) { + position_float[E_AXIS] = e; // Behave as if the move really took place, but ignore E part + position[E_AXIS] = target[E_AXIS]; + lin_dist_e = 0; + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); + } + #endif // PREVENT_LENGTHY_EXTRUDE + } + #endif // LIN_ADVANCE && (PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE) + + #if ENABLED(LIN_ADVANCE) + if (lin_dist_e > 0) + lin_dist_xy = HYPOT(a - position_float[X_AXIS], b - position_float[Y_AXIS]); + #endif + + /* <-- add a slash to enable + SERIAL_ECHOPAIR(" buffer_segment FR:", fr_mm_s); + #if IS_KINEMATIC + SERIAL_ECHOPAIR(" A:", a); + SERIAL_ECHOPAIR(" (", position[A_AXIS]); + SERIAL_ECHOPAIR("->", target[A_AXIS]); + SERIAL_ECHOPAIR(") B:", b); + #else + SERIAL_ECHOPAIR(" X:", a); + SERIAL_ECHOPAIR(" (", position[X_AXIS]); + SERIAL_ECHOPAIR("->", target[X_AXIS]); + SERIAL_ECHOPAIR(") Y:", b); + #endif + SERIAL_ECHOPAIR(" (", position[Y_AXIS]); + SERIAL_ECHOPAIR("->", target[Y_AXIS]); + #if ENABLED(DELTA) + SERIAL_ECHOPAIR(") C:", c); + #else + SERIAL_ECHOPAIR(") Z:", c); + #endif + SERIAL_ECHOPAIR(" (", position[Z_AXIS]); + SERIAL_ECHOPAIR("->", target[Z_AXIS]); + SERIAL_ECHOPAIR(") E:", e); + SERIAL_ECHOPAIR(" (", position[E_AXIS]); + SERIAL_ECHOPAIR("->", target[E_AXIS]); + SERIAL_ECHOLNPGM(")"); + //*/ + + // Always split the first move into two (if not homing or probing) + if (!blocks_queued()) { + + #define _BETWEEN(A) (position[A##_AXIS] + target[A##_AXIS]) >> 1 + const int32_t between[XYZE] = { _BETWEEN(X), _BETWEEN(Y), _BETWEEN(Z), _BETWEEN(E) }; + DISABLE_STEPPER_DRIVER_INTERRUPT(); + + #if ENABLED(LIN_ADVANCE) + lin_dist_xy *= 0.5; + lin_dist_e *= 0.5; + #endif + + _buffer_steps(between, fr_mm_s, extruder); + + #if ENABLED(LIN_ADVANCE) + position_float[X_AXIS] = (position_float[X_AXIS] + a) * 0.5; + position_float[Y_AXIS] = (position_float[Y_AXIS] + b) * 0.5; + //position_float[Z_AXIS] = (position_float[Z_AXIS] + c) * 0.5; + position_float[E_AXIS] = (position_float[E_AXIS] + e) * 0.5; + #endif + + const uint8_t next = block_buffer_head; + _buffer_steps(target, fr_mm_s, extruder); + SBI(block_buffer[next].flag, BLOCK_BIT_CONTINUED); + ENABLE_STEPPER_DRIVER_INTERRUPT(); + } + else + _buffer_steps(target, fr_mm_s, extruder); + stepper.wake_up(); -} // buffer_line() + #if ENABLED(LIN_ADVANCE) + position_float[X_AXIS] = a; + position_float[Y_AXIS] = b; + //position_float[Z_AXIS] = c; + position_float[E_AXIS] = e; + #endif +} // buffer_segment() /** * Directly set the planner XYZ position (and stepper positions) @@ -1437,14 +1553,14 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c #else #define _EINDEX E_AXIS #endif - long na = position[X_AXIS] = LROUND(a * axis_steps_per_mm[X_AXIS]), - nb = position[Y_AXIS] = LROUND(b * axis_steps_per_mm[Y_AXIS]), - nc = position[Z_AXIS] = LROUND(c * axis_steps_per_mm[Z_AXIS]), - ne = position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); + const int32_t na = position[X_AXIS] = LROUND(a * axis_steps_per_mm[X_AXIS]), + nb = position[Y_AXIS] = LROUND(b * axis_steps_per_mm[Y_AXIS]), + nc = position[Z_AXIS] = LROUND(c * axis_steps_per_mm[Z_AXIS]), + ne = position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); #if ENABLED(LIN_ADVANCE) position_float[X_AXIS] = a; position_float[Y_AXIS] = b; - position_float[Z_AXIS] = c; + //position_float[Z_AXIS] = c; position_float[E_AXIS] = e; #endif stepper.set_position(na, nb, nc, ne); @@ -1452,18 +1568,18 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c ZERO(previous_speed); } -void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) { +void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) { #if PLANNER_LEVELING - float lpos[XYZ] = { position[X_AXIS], position[Y_AXIS], position[Z_AXIS] }; - apply_leveling(lpos); + float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] }; + apply_leveling(raw); #else - const float * const lpos = position; + const float (&raw)[XYZE] = cart; #endif #if IS_KINEMATIC - inverse_kinematics(lpos); - _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], position[E_AXIS]); + inverse_kinematics(raw); + _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]); #else - _set_position_mm(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], position[E_AXIS]); + _set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]); #endif } diff --git a/Marlin/planner.h b/Marlin/planner.h index c47eebd8fa..23f13bf962 100644 --- a/Marlin/planner.h +++ b/Marlin/planner.h @@ -53,14 +53,18 @@ enum BlockFlagBit { BLOCK_BIT_START_FROM_FULL_HALT, // The block is busy - BLOCK_BIT_BUSY + BLOCK_BIT_BUSY, + + // The block is segment 2+ of a longer move + BLOCK_BIT_CONTINUED }; enum BlockFlag { BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE), BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH), BLOCK_FLAG_START_FROM_FULL_HALT = _BV(BLOCK_BIT_START_FROM_FULL_HALT), - BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY) + BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY), + BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED) }; /** @@ -119,34 +123,54 @@ typedef struct { uint8_t valve_pressure, e_to_p_pressure; #endif - uint32_t segment_time; + uint32_t segment_time_us; } block_t; #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) class Planner { - public: /** - * A ring buffer of moves described in steps + * The move buffer, calculated in stepper steps + * + * block_buffer is a ring buffer... + * + * head,tail : indexes for write,read + * head==tail : the buffer is empty + * head!=tail : blocks are in the buffer + * head==(tail-1)%size : the buffer is full + * + * Writer of head is Planner::buffer_segment(). + * Reader of tail is Stepper::isr(). Always consider tail busy / read-only */ static block_t block_buffer[BLOCK_BUFFER_SIZE]; - static volatile uint8_t block_buffer_head, // Index of the next block to be pushed - block_buffer_tail; + static volatile uint8_t block_buffer_head, // Index of the next block to be pushed + block_buffer_tail; // Index of the busy block, if any #if ENABLED(DISTINCT_E_FACTORS) - static uint8_t last_extruder; // Respond to extruder change + static uint8_t last_extruder; // Respond to extruder change #endif - static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second + static int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder + + static float e_factor[EXTRUDERS]; // The flow percentage and volumetric multiplier combine to scale E movement + + #if DISABLED(NO_VOLUMETRICS) + static float filament_size[EXTRUDERS], // diameter of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder + volumetric_area_nominal, // Nominal cross-sectional area + volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner + // May be auto-adjusted by a filament width sensor + #endif + + static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second axis_steps_per_mm[XYZE_N], steps_to_mm[XYZE_N]; static uint32_t max_acceleration_steps_per_s2[XYZE_N], - max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software + max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override - static millis_t min_segment_time; + static uint32_t min_segment_time_us; // Use 'M205 B<µs>' to override static float min_feedrate_mm_s, acceleration, // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX retract_acceleration, // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX @@ -154,19 +178,39 @@ class Planner { max_jerk[XYZE], // The largest speed change requiring no acceleration min_travel_feedrate_mm_s; - #if HAS_ABL - static bool abl_enabled; // Flag that bed leveling is enabled + #if HAS_LEVELING + static bool leveling_active; // Flag that bed leveling is enabled #if ABL_PLANAR static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level #endif - #endif - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - static float z_fade_height, inverse_z_fade_height; + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + static float z_fade_height, inverse_z_fade_height; + #endif + #else + static constexpr bool leveling_active = false; #endif #if ENABLED(LIN_ADVANCE) - static float extruder_advance_k, advance_ed_ratio; + static float extruder_advance_k, advance_ed_ratio, + position_float[XYZE], + lin_dist_xy, lin_dist_e; + #endif + + #if ENABLED(SKEW_CORRECTION) + #if ENABLED(SKEW_CORRECTION_GCODE) + static float xy_skew_factor; + #else + static constexpr float xy_skew_factor = XY_SKEW_FACTOR; + #endif + #if ENABLED(SKEW_CORRECTION_FOR_Z) + #if ENABLED(SKEW_CORRECTION_GCODE) + static float xz_skew_factor, yz_skew_factor; + #else + static constexpr float xz_skew_factor = XZ_SKEW_FACTOR, yz_skew_factor = YZ_SKEW_FACTOR; + #endif + #else + static constexpr float xz_skew_factor = 0, yz_skew_factor = 0; + #endif #endif private: @@ -175,7 +219,7 @@ class Planner { * The current position of the tool in absolute steps * Recalculated if any axis_steps_per_mm are changed by gcode */ - static long position[NUM_AXIS]; + static int32_t position[NUM_AXIS]; /** * Speed of previous path line segment @@ -192,6 +236,10 @@ class Planner { */ static uint32_t cutoff_long; + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + static float last_fade_z; + #endif + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) /** * Counters to manage disabling inactive extruders @@ -201,15 +249,11 @@ class Planner { #ifdef XY_FREQUENCY_LIMIT // Used for the frequency limit - #define MAX_FREQ_TIME long(1000000.0/XY_FREQUENCY_LIMIT) + #define MAX_FREQ_TIME_US (uint32_t)(1000000.0 / XY_FREQUENCY_LIMIT) // Old direction bits. Used for speed calculations static unsigned char old_direction_bits; // Segment times (in µs). Used for speed calculations - static long axis_segment_time[2][3]; - #endif - - #if ENABLED(LIN_ADVANCE) - static float position_float[NUM_AXIS]; + static uint32_t axis_segment_time_us[2][3]; #endif #if ENABLED(ULTRA_LCD) @@ -233,50 +277,156 @@ class Planner { static void reset_acceleration_rates(); static void refresh_positioning(); + FORCE_INLINE static void refresh_e_factor(const uint8_t e) { + e_factor[e] = (flow_percentage[e] * 0.01 + #if DISABLED(NO_VOLUMETRICS) + * volumetric_multiplier[e] + #endif + ); + } + // Manage fans, paste pressure, etc. static void check_axes_activity(); /** * Number of moves currently in the planner */ - static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); } + FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); } - static bool is_full() { return (block_buffer_tail == BLOCK_MOD(block_buffer_head + 1)); } + FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); } + + // Update multipliers based on new diameter measurements + static void calculate_volumetric_multipliers(); + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + void calculate_volumetric_for_width_sensor(const int8_t encoded_ratio); + #endif + + #if DISABLED(NO_VOLUMETRICS) + + FORCE_INLINE static void set_filament_size(const uint8_t e, const float &v) { + filament_size[e] = v; + // make sure all extruders have some sane value for the filament size + for (uint8_t i = 0; i < COUNT(filament_size); i++) + if (!filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; + } + + #endif + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + + /** + * Get the Z leveling fade factor based on the given Z height, + * re-calculating only when needed. + * + * Returns 1.0 if planner.z_fade_height is 0.0. + * Returns 0.0 if Z is past the specified 'Fade Height'. + */ + inline static float fade_scaling_factor_for_z(const float &rz) { + static float z_fade_factor = 1.0; + if (z_fade_height) { + if (rz >= z_fade_height) return 0.0; + if (last_fade_z != rz) { + last_fade_z = rz; + z_fade_factor = 1.0 - rz * inverse_z_fade_height; + } + return z_fade_factor; + } + return 1.0; + } + + FORCE_INLINE static void force_fade_recalc() { last_fade_z = -999.999; } + + FORCE_INLINE static void set_z_fade_height(const float &zfh) { + z_fade_height = zfh > 0 ? zfh : 0; + inverse_z_fade_height = RECIPROCAL(z_fade_height); + force_fade_recalc(); + } + + FORCE_INLINE static bool leveling_active_at_z(const float &rz) { + return !z_fade_height || rz < z_fade_height; + } + + #else + + FORCE_INLINE static float fade_scaling_factor_for_z(const float &rz) { + UNUSED(rz); + return 1.0; + } + + FORCE_INLINE static bool leveling_active_at_z(const float &rz) { UNUSED(rz); return true; } + + #endif + + #if ENABLED(SKEW_CORRECTION) + + FORCE_INLINE static void skew(float &cx, float &cy, const float &cz) { + if (WITHIN(cx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(cy, Y_MIN_POS + 1, Y_MAX_POS)) { + const float sx = cx - cy * xy_skew_factor - cz * (xz_skew_factor - (xy_skew_factor * yz_skew_factor)), + sy = cy - cz * yz_skew_factor; + if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) { + cx = sx; cy = sy; + } + } + } + + FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) { + if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) { + const float sx = cx + cy * xy_skew_factor + cz * xz_skew_factor, + sy = cy + cz * yz_skew_factor; + if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) { + cx = sx; cy = sy; + } + } + } + + #endif // SKEW_CORRECTION #if PLANNER_LEVELING - #define ARG_X float lx - #define ARG_Y float ly - #define ARG_Z float lz + #define ARG_X float rx + #define ARG_Y float ry + #define ARG_Z float rz /** * Apply leveling to transform a cartesian position * as it will be given to the planner and steppers. */ - static void apply_leveling(float &lx, float &ly, float &lz); - static void apply_leveling(float logical[XYZ]) { apply_leveling(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS]); } - static void unapply_leveling(float logical[XYZ]); + static void apply_leveling(float &rx, float &ry, float &rz); + static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); } + static void unapply_leveling(float raw[XYZ]); #else - #define ARG_X const float &lx - #define ARG_Y const float &ly - #define ARG_Z const float &lz + #define ARG_X const float &rx + #define ARG_Y const float &ry + #define ARG_Z const float &rz #endif /** - * Planner::_buffer_line + * Planner::_buffer_steps * - * Add a new direct linear movement to the buffer. + * Add a new linear movement to the buffer (in terms of steps). * - * Leveling and kinematics should be applied ahead of this. + * target - target position in steps units + * fr_mm_s - (target) speed of the move + * extruder - target extruder + */ + static void _buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const uint8_t extruder); + + /** + * Planner::buffer_segment * - * a,b,c,e - target position in mm or degrees - * fr_mm_s - (target) speed of the move (mm/s) + * Add a new linear movement to the buffer in axis units. + * + * Leveling and kinematics should be applied ahead of calling this. + * + * a,b,c,e - target positions in mm and/or degrees + * fr_mm_s - (target) speed of the move * extruder - target extruder */ - static void _buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder); + static void buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder); static void _set_position_mm(const float &a, const float &b, const float &c, const float &e); @@ -288,15 +438,15 @@ class Planner { * Kinematic machines should call buffer_line_kinematic (for leveled moves). * (Cartesians may also call buffer_line_kinematic.) * - * lx,ly,lz,e - target position in mm or degrees + * rx,ry,rz,e - target position in mm or degrees * fr_mm_s - (target) speed of the move (mm/s) * extruder - target extruder */ - static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) { + FORCE_INLINE static void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) { #if PLANNER_LEVELING && IS_CARTESIAN - apply_leveling(lx, ly, lz); + apply_leveling(rx, ry, rz); #endif - _buffer_line(lx, ly, lz, e, fr_mm_s, extruder); + buffer_segment(rx, ry, rz, e, fr_mm_s, extruder); } /** @@ -304,22 +454,22 @@ class Planner { * The target is cartesian, it's translated to delta/scara if * needed. * - * ltarget - x,y,z,e CARTESIAN target in mm + * cart - x,y,z,e CARTESIAN target in mm * fr_mm_s - (target) speed of the move (mm/s) * extruder - target extruder */ - static FORCE_INLINE void buffer_line_kinematic(const float ltarget[XYZE], const float &fr_mm_s, const uint8_t extruder) { + FORCE_INLINE static void buffer_line_kinematic(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder) { #if PLANNER_LEVELING - float lpos[XYZ] = { ltarget[X_AXIS], ltarget[Y_AXIS], ltarget[Z_AXIS] }; - apply_leveling(lpos); + float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] }; + apply_leveling(raw); #else - const float * const lpos = ltarget; + const float (&raw)[XYZE] = cart; #endif #if IS_KINEMATIC - inverse_kinematics(lpos); - _buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); + inverse_kinematics(raw); + buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder); #else - _buffer_line(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); + buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder); #endif } @@ -332,16 +482,16 @@ class Planner { * * Clears previous speed values. */ - static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) { + FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) { #if PLANNER_LEVELING && IS_CARTESIAN - apply_leveling(lx, ly, lz); + apply_leveling(rx, ry, rz); #endif - _set_position_mm(lx, ly, lz, e); + _set_position_mm(rx, ry, rz, e); } - static void set_position_mm_kinematic(const float position[NUM_AXIS]); + static void set_position_mm_kinematic(const float (&cart)[XYZE]); static void set_position_mm(const AxisEnum axis, const float &v); - static FORCE_INLINE void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); } - static FORCE_INLINE void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); } + FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); } + FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); } /** * Sync from the stepper positions. (e.g., after an interrupted move) @@ -354,23 +504,34 @@ class Planner { static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); } /** - * "Discards" the block and "releases" the memory. + * "Discard" the block and "release" the memory. * Called when the current block is no longer needed. */ - static void discard_current_block() { + FORCE_INLINE static void discard_current_block() { if (blocks_queued()) block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1); } + /** + * "Discard" the next block if it's continued. + * Called after an interrupted move to throw away the rest of the move. + */ + FORCE_INLINE static bool discard_continued_block() { + const bool discard = blocks_queued() && TEST(block_buffer[block_buffer_tail].flag, BLOCK_BIT_CONTINUED); + if (discard) discard_current_block(); + return discard; + } + /** * The current block. NULL if the buffer is empty. * This also marks the block as busy. + * WARNING: Called from Stepper ISR context! */ static block_t* get_current_block() { if (blocks_queued()) { - block_t* block = &block_buffer[block_buffer_tail]; + block_t * const block = &block_buffer[block_buffer_tail]; #if ENABLED(ULTRA_LCD) - block_buffer_runtime_us -= block->segment_time; //We can't be sure how long an active block will take, so don't count it. + block_buffer_runtime_us -= block->segment_time_us; // We can't be sure how long an active block will take, so don't count it. #endif SBI(block->flag, BLOCK_BIT_BUSY); return block; @@ -418,8 +579,8 @@ class Planner { /** * Get the index of the next / previous block in the ring buffer */ - static int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); } - static int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); } + static constexpr int8_t next_block_index(const int8_t block_index) { return BLOCK_MOD(block_index + 1); } + static constexpr int8_t prev_block_index(const int8_t block_index) { return BLOCK_MOD(block_index - 1); } /** * Calculate the distance (not time) it takes to accelerate @@ -431,7 +592,7 @@ class Planner { } /** - * Return the point at which you must start braking (at the rate of -'acceleration') if + * Return the point at which you must start braking (at the rate of -'accel') if * you start at 'initial_rate', accelerate (until reaching the point), and want to end at * 'final_rate' after traveling 'distance'. * @@ -454,8 +615,8 @@ class Planner { static void calculate_trapezoid_for_block(block_t* const block, const float &entry_factor, const float &exit_factor); - static void reverse_pass_kernel(block_t* const current, const block_t *next); - static void forward_pass_kernel(const block_t *previous, block_t* const current); + static void reverse_pass_kernel(block_t* const current, const block_t * const next); + static void forward_pass_kernel(const block_t * const previous, block_t* const current); static void reverse_pass(); static void forward_pass(); diff --git a/Marlin/planner_bezier.cpp b/Marlin/planner_bezier.cpp index 71697e04ae..d07863d13c 100644 --- a/Marlin/planner_bezier.cpp +++ b/Marlin/planner_bezier.cpp @@ -107,10 +107,10 @@ inline static float dist1(float x1, float y1, float x2, float y2) { return FABS( */ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) { // Absolute first and second control points are recovered. - float first0 = position[X_AXIS] + offset[0]; - float first1 = position[Y_AXIS] + offset[1]; - float second0 = target[X_AXIS] + offset[2]; - float second1 = target[Y_AXIS] + offset[3]; + const float first0 = position[X_AXIS] + offset[0], + first1 = position[Y_AXIS] + offset[1], + second0 = target[X_AXIS] + offset[2], + second1 = target[Y_AXIS] + offset[3]; float t = 0.0; float bez_target[4]; @@ -134,15 +134,15 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS] bool did_reduce = false; float new_t = t + step; NOMORE(new_t, 1.0); - float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t); - float new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t); + float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t), + new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t); for (;;) { if (new_t - t < (MIN_STEP)) break; - float candidate_t = 0.5 * (t + new_t); - float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); - float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); - float interp_pos0 = 0.5 * (bez_target[X_AXIS] + new_pos0); - float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + new_pos1); + const float candidate_t = 0.5 * (t + new_t), + candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t), + candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t), + interp_pos0 = 0.5 * (bez_target[X_AXIS] + new_pos0), + interp_pos1 = 0.5 * (bez_target[Y_AXIS] + new_pos1); if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break; new_t = candidate_t; new_pos0 = candidate_pos0; @@ -153,12 +153,12 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS] // If we did not reduce the step, maybe we should enlarge it. if (!did_reduce) for (;;) { if (new_t - t > MAX_STEP) break; - float candidate_t = t + 2.0 * (new_t - t); + const float candidate_t = t + 2.0 * (new_t - t); if (candidate_t >= 1.0) break; - float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); - float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); - float interp_pos0 = 0.5 * (bez_target[X_AXIS] + candidate_pos0); - float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + candidate_pos1); + const float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t), + candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t), + interp_pos0 = 0.5 * (bez_target[X_AXIS] + candidate_pos0), + interp_pos1 = 0.5 * (bez_target[Y_AXIS] + candidate_pos1); if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break; new_t = candidate_t; new_pos0 = candidate_pos0; diff --git a/Marlin/point_t.h b/Marlin/point_t.h index 360abce649..37ade7eba7 100644 --- a/Marlin/point_t.h +++ b/Marlin/point_t.h @@ -31,22 +31,9 @@ * @param x The x-coordinate of the point. * @param y The y-coordinate of the point. * @param z The z-coordinate of the point. - * @param e The e-coordinate of the point. */ struct point_t { - float x; - float y; - float z; - float e; - - /** - * @brief Two dimensional point constructor - * - * @param x The x-coordinate of the point. - * @param y The y-coordinate of the point. - */ - point_t(float const x, float const y) - : point_t(x, y, NAN, NAN) {} + float x, y, z; /** * @brief Three dimensional point constructor @@ -55,23 +42,16 @@ struct point_t { * @param y The y-coordinate of the point. * @param z The z-coordinate of the point. */ - point_t(float const x, float const y, float const z) - : point_t(x, y, z, NAN) {} + point_t(const float x, const float y, const float z) : x(x), y(y), z(z) {} /** - * @brief Tree dimensional point constructor with extrusion length + * @brief Two dimensional point constructor * * @param x The x-coordinate of the point. * @param y The y-coordinate of the point. - * @param z The z-coordinate of the point. - * @param e The e-coordinate of the point. */ - point_t(float const x, float const y, float const z, float const e) { - this->x = x; - this->y = y; - this->z = z; - this->e = e; - } + point_t(const float x, const float y) : point_t(x, y, NAN) {} + }; #endif // __POINT_T__ diff --git a/Marlin/serial.h b/Marlin/serial.h index a4b6799dd8..a2fd4306d1 100644 --- a/Marlin/serial.h +++ b/Marlin/serial.h @@ -26,7 +26,7 @@ #include "MarlinConfig.h" #ifdef USBCON - #include "HardwareSerial.h" + #include #if ENABLED(BLUETOOTH) #define MYSERIAL bluetoothSerial #else diff --git a/Marlin/speed_lookuptable.h b/Marlin/speed_lookuptable.h index f29199b732..72e96e0f86 100644 --- a/Marlin/speed_lookuptable.h +++ b/Marlin/speed_lookuptable.h @@ -23,7 +23,7 @@ #ifndef SPEED_LOOKUPTABLE_H #define SPEED_LOOKUPTABLE_H -#include "Marlin.h" +#include "MarlinConfig.h" #if F_CPU == 16000000 diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index 2b86c4287c..ed9333716e 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -54,6 +54,10 @@ #include "cardreader.h" #include "speed_lookuptable.h" +#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) + #include "ubl.h" +#endif + #if HAS_DIGIPOTSS #include #endif @@ -62,17 +66,13 @@ Stepper stepper; // Singleton // public: -#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) - extern bool ubl_lcd_map_control; -#endif - block_t* Stepper::current_block = NULL; // A pointer to the block currently being traced #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) bool Stepper::abort_on_endstop_hit = false; #endif -#if ENABLED(Z_DUAL_ENDSTOPS) +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) bool Stepper::performing_homing = false; #endif @@ -83,11 +83,16 @@ block_t* Stepper::current_block = NULL; // A pointer to the block currently bei // private: uint8_t Stepper::last_direction_bits = 0; // The next stepping-bits to be output -uint16_t Stepper::cleaning_buffer_counter = 0; +int16_t Stepper::cleaning_buffer_counter = 0; +#if ENABLED(X_DUAL_ENDSTOPS) + bool Stepper::locked_x_motor = false, Stepper::locked_x2_motor = false; +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + bool Stepper::locked_y_motor = false, Stepper::locked_y2_motor = false; +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - bool Stepper::locked_z_motor = false; - bool Stepper::locked_z2_motor = false; + bool Stepper::locked_z_motor = false, Stepper::locked_z2_motor = false; #endif long Stepper::counter_X = 0, @@ -136,32 +141,61 @@ volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; long Stepper::counter_m[MIXING_STEPPERS]; #endif -unsigned short Stepper::acc_step_rate; // needed for deceleration start point uint8_t Stepper::step_loops, Stepper::step_loops_nominal; -unsigned short Stepper::OCR1A_nominal; + +uint16_t Stepper::OCR1A_nominal, + Stepper::acc_step_rate; // needed for deceleration start point volatile long Stepper::endstops_trigsteps[XYZ]; +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + #define LOCKED_X_MOTOR locked_x_motor + #define LOCKED_Y_MOTOR locked_y_motor + #define LOCKED_Z_MOTOR locked_z_motor + #define LOCKED_X2_MOTOR locked_x2_motor + #define LOCKED_Y2_MOTOR locked_y2_motor + #define LOCKED_Z2_MOTOR locked_z2_motor + #define DUAL_ENDSTOP_APPLY_STEP(AXIS,v) \ + if (performing_homing) { \ + if (AXIS##_HOME_DIR < 0) { \ + if (!(TEST(endstops.old_endstop_bits, AXIS##_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, AXIS##2_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v); \ + } \ + else { \ + if (!(TEST(endstops.old_endstop_bits, AXIS##_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, AXIS##2_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v); \ + } \ + } \ + else { \ + AXIS##_STEP_WRITE(v); \ + AXIS##2_STEP_WRITE(v); \ + } +#endif + #if ENABLED(X_DUAL_STEPPER_DRIVERS) #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0) - #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) -#elif ENABLED(DUAL_X_CARRIAGE) - #define X_APPLY_DIR(v,ALWAYS) \ - if (extruder_duplication_enabled || ALWAYS) { \ - X_DIR_WRITE(v); \ - X2_DIR_WRITE(v); \ - } \ - else { \ - if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ - } - #define X_APPLY_STEP(v,ALWAYS) \ - if (extruder_duplication_enabled || ALWAYS) { \ - X_STEP_WRITE(v); \ - X2_STEP_WRITE(v); \ - } \ - else { \ - if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ - } + #if ENABLED(DUAL_X_CARRIAGE) + #define X_APPLY_DIR(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_DIR_WRITE(v); \ + X2_DIR_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + } + #define X_APPLY_STEP(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_STEP_WRITE(v); \ + X2_STEP_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + } + #elif ENABLED(X_DUAL_ENDSTOPS) + #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v) + #else + #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) + #endif #else #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) @@ -169,7 +203,11 @@ volatile long Stepper::endstops_trigsteps[XYZ]; #if ENABLED(Y_DUAL_STEPPER_DRIVERS) #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0) - #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v) + #else + #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) + #endif #else #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) @@ -178,21 +216,7 @@ volatile long Stepper::endstops_trigsteps[XYZ]; #if ENABLED(Z_DUAL_STEPPER_DRIVERS) #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0) #if ENABLED(Z_DUAL_ENDSTOPS) - #define Z_APPLY_STEP(v,Q) \ - if (performing_homing) { \ - if (Z_HOME_DIR < 0) { \ - if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ - if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ - } \ - else { \ - if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ - if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ - } \ - } \ - else { \ - Z_STEP_WRITE(v); \ - Z2_STEP_WRITE(v); \ - } + #define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v) #else #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0) #endif @@ -263,9 +287,6 @@ volatile long Stepper::endstops_trigsteps[XYZ]; // Some useful constants -#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) - /** * __________________________ * /| |\ _________________ ^ @@ -361,8 +382,8 @@ void Stepper::isr() { uint16_t ocr_val; - #define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch - #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms + #define ENDSTOP_NOMINAL_OCR_VAL 3000 // Check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch + #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms #if DISABLED(LIN_ADVANCE) // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) @@ -373,9 +394,13 @@ void Stepper::isr() { #define _SPLIT(L) (ocr_val = (uint16_t)L) #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #define SPLIT(L) _SPLIT(L) - #else // sample endstops in between step pulses + + #else // !ENDSTOP_INTERRUPTS_FEATURE : Sample endstops between stepping ISRs + static uint32_t step_remaining = 0; + #define SPLIT(L) do { \ _SPLIT(L); \ if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \ @@ -387,41 +412,44 @@ void Stepper::isr() { if (step_remaining && ENDSTOPS_ENABLED) { // Just check endstops - not yet time for a step endstops.update(); - if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) { - step_remaining -= ENDSTOP_NOMINAL_OCR_VAL; - ocr_val = ENDSTOP_NOMINAL_OCR_VAL; - } - else { - ocr_val = step_remaining; - step_remaining = 0; // last one before the ISR that does the step - } + // Next ISR either for endstops or stepping + ocr_val = step_remaining <= ENDSTOP_NOMINAL_OCR_VAL ? step_remaining : ENDSTOP_NOMINAL_OCR_VAL; + step_remaining -= ocr_val; _NEXT_ISR(ocr_val); - NOLESS(OCR1A, TCNT1 + 16); - _ENABLE_ISRs(); // re-enable ISRs return; } - #endif + #endif // !ENDSTOP_INTERRUPTS_FEATURE + + // + // When cleaning, discard the current block and run fast + // if (cleaning_buffer_counter) { - --cleaning_buffer_counter; - current_block = NULL; - planner.discard_current_block(); - #ifdef SD_FINISHED_RELEASECOMMAND - if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); - #endif - _NEXT_ISR(200); // Run at max speed - 10 KHz - _ENABLE_ISRs(); // re-enable ISRs + if (cleaning_buffer_counter < 0) { // Count up for endstop hit + if (current_block) planner.discard_current_block(); // Discard the active block that led to the trigger + if (!planner.discard_continued_block()) // Discard next CONTINUED block + cleaning_buffer_counter = 0; // Keep discarding until non-CONTINUED + } + else { + planner.discard_current_block(); + --cleaning_buffer_counter; // Count down for abort print + #ifdef SD_FINISHED_RELEASECOMMAND + if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + #endif + } + current_block = NULL; // Prep to get a new block after cleaning + _NEXT_ISR(200); // Run at max speed - 10 KHz + _ENABLE_ISRs(); return; } // If there is no current block, attempt to pop one from the buffer if (!current_block) { // Anything in the buffer? - current_block = planner.get_current_block(); - if (current_block) { + if ((current_block = planner.get_current_block())) { trapezoid_generator_reset(); // Initialize Bresenham counters to 1/2 the ceiling @@ -684,12 +712,12 @@ void Stepper::isr() { NOMORE(acc_step_rate, current_block->nominal_rate); // step_rate to timer interval - const uint16_t timer = calc_timer(acc_step_rate); + const uint16_t interval = calc_timer_interval(acc_step_rate); - SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL _NEXT_ISR(ocr_val); - acceleration_time += timer; + acceleration_time += interval; #if ENABLED(LIN_ADVANCE) @@ -701,7 +729,7 @@ void Stepper::isr() { current_estep_rate[TOOL_E_INDEX] = ((uint32_t)acc_step_rate * current_block->abs_adv_steps_multiplier8) >> 17; #endif } - eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], interval, step_loops); #endif // LIN_ADVANCE } @@ -717,12 +745,12 @@ void Stepper::isr() { step_rate = current_block->final_rate; // step_rate to timer interval - const uint16_t timer = calc_timer(step_rate); + const uint16_t interval = calc_timer_interval(step_rate); - SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + SPLIT(interval); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL _NEXT_ISR(ocr_val); - deceleration_time += timer; + deceleration_time += interval; #if ENABLED(LIN_ADVANCE) @@ -734,7 +762,7 @@ void Stepper::isr() { current_estep_rate[TOOL_E_INDEX] = ((uint32_t)step_rate * current_block->abs_adv_steps_multiplier8) >> 17; #endif } - eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], interval, step_loops); #endif // LIN_ADVANCE } @@ -749,7 +777,7 @@ void Stepper::isr() { #endif - SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL _NEXT_ISR(ocr_val); // ensure we're running at the correct step rate, even if we just came off an acceleration @@ -928,6 +956,16 @@ void Stepper::init() { tmc2130_init(); #endif + // Init TMC2208 Steppers + #if ENABLED(HAVE_TMC2208) + tmc2208_init(); + #endif + + // TRAMS, TMC2130 and TMC2208 advanced settings + #if HAS_TRINAMIC + TMC_ADV() + #endif + // Init L6470 Steppers #if ENABLED(HAVE_L6470DRIVER) L6470_init(); @@ -1100,9 +1138,9 @@ void Stepper::init() { /** - * Block until all buffered steps are executed + * Block until all buffered steps are executed / cleaned */ -void Stepper::synchronize() { while (planner.blocks_queued()) idle(); } +void Stepper::synchronize() { while (planner.blocks_queued() || cleaning_buffer_counter) idle(); } /** * Set the stepper positions directly in steps @@ -1161,7 +1199,7 @@ void Stepper::set_e_position(const long &e) { /** * Get a stepper's position in steps. */ -long Stepper::position(AxisEnum axis) { +long Stepper::position(const AxisEnum axis) { CRITICAL_SECTION_START; const long count_pos = count_position[axis]; CRITICAL_SECTION_END; @@ -1172,7 +1210,7 @@ long Stepper::position(AxisEnum axis) { * Get an axis position according to stepper position(s) * For CORE machines apply translation from ABC to XYZ. */ -float Stepper::get_axis_position_mm(AxisEnum axis) { +float Stepper::get_axis_position_mm(const AxisEnum axis) { float axis_steps; #if IS_CORE // Requesting one of the "core" axes? @@ -1200,12 +1238,7 @@ void Stepper::finish_and_disable() { } void Stepper::quick_stop() { - #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) - if (!ubl_lcd_map_control) - cleaning_buffer_counter = 5000; - #else - cleaning_buffer_counter = 5000; - #endif + cleaning_buffer_counter = 5000; DISABLE_STEPPER_DRIVER_INTERRUPT(); while (planner.blocks_queued()) planner.discard_current_block(); current_block = NULL; @@ -1231,6 +1264,7 @@ void Stepper::endstop_triggered(AxisEnum axis) { #endif // !COREXY && !COREXZ && !COREYZ kill_current_block(); + cleaning_buffer_counter = -1; // Discard the rest of the move } void Stepper::report_positions() { diff --git a/Marlin/stepper.h b/Marlin/stepper.h index 682d684f86..0115125e52 100644 --- a/Marlin/stepper.h +++ b/Marlin/stepper.h @@ -52,6 +52,9 @@ class Stepper; extern Stepper stepper; +#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) + // intRes = intIn1 * intIn2 >> 16 // uses: // r26 to store 0 @@ -87,7 +90,7 @@ class Stepper { static bool abort_on_endstop_hit; #endif - #if ENABLED(Z_DUAL_ENDSTOPS) + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) static bool performing_homing; #endif @@ -98,11 +101,18 @@ class Stepper { static uint32_t motor_current_setting[3]; #endif + static int16_t cleaning_buffer_counter; + private: static uint8_t last_direction_bits; // The next stepping-bits to be output - static uint16_t cleaning_buffer_counter; + #if ENABLED(X_DUAL_ENDSTOPS) + static bool locked_x_motor, locked_x2_motor; + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + static bool locked_y_motor, locked_y2_motor; + #endif #if ENABLED(Z_DUAL_ENDSTOPS) static bool locked_z_motor, locked_z2_motor; #endif @@ -128,10 +138,10 @@ class Stepper { #endif // !LIN_ADVANCE static long acceleration_time, deceleration_time; - //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; - static unsigned short acc_step_rate; // needed for deceleration start point static uint8_t step_loops, step_loops_nominal; - static unsigned short OCR1A_nominal; + + static uint16_t OCR1A_nominal, + acc_step_rate; // needed for deceleration start point static volatile long endstops_trigsteps[XYZ]; static volatile long endstops_stepsTotal, endstops_stepsDone; @@ -199,7 +209,7 @@ class Stepper { // // Get the position of a stepper, in steps // - static long position(AxisEnum axis); + static long position(const AxisEnum axis); // // Report the positions of the steppers, in steps @@ -209,13 +219,13 @@ class Stepper { // // Get the position (mm) of an axis based on stepper position(s) // - static float get_axis_position_mm(AxisEnum axis); + static float get_axis_position_mm(const AxisEnum axis); // // SCARA AB axes are in degrees, not mm // #if IS_SCARA - static FORCE_INLINE float get_axis_position_degrees(AxisEnum axis) { return get_axis_position_mm(axis); } + FORCE_INLINE static float get_axis_position_degrees(const AxisEnum axis) { return get_axis_position_mm(axis); } #endif // @@ -237,7 +247,7 @@ class Stepper { // // The direction of a single motor // - static FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); } + FORCE_INLINE static bool motor_direction(const AxisEnum axis) { return TEST(last_direction_bits, axis); } #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM static void digitalPotWrite(const int16_t address, const int16_t value); @@ -250,10 +260,20 @@ class Stepper { static void microstep_readings(); #endif + #if ENABLED(X_DUAL_ENDSTOPS) + FORCE_INLINE static void set_homing_flag_x(const bool state) { performing_homing = state; } + FORCE_INLINE static void set_x_lock(const bool state) { locked_x_motor = state; } + FORCE_INLINE static void set_x2_lock(const bool state) { locked_x2_motor = state; } + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + FORCE_INLINE static void set_homing_flag_y(const bool state) { performing_homing = state; } + FORCE_INLINE static void set_y_lock(const bool state) { locked_y_motor = state; } + FORCE_INLINE static void set_y2_lock(const bool state) { locked_y2_motor = state; } + #endif #if ENABLED(Z_DUAL_ENDSTOPS) - static FORCE_INLINE void set_homing_flag(const bool state) { performing_homing = state; } - static FORCE_INLINE void set_z_lock(const bool state) { locked_z_motor = state; } - static FORCE_INLINE void set_z2_lock(const bool state) { locked_z2_motor = state; } + FORCE_INLINE static void set_homing_flag_z(const bool state) { performing_homing = state; } + FORCE_INLINE static void set_z_lock(const bool state) { locked_z_motor = state; } + FORCE_INLINE static void set_z2_lock(const bool state) { locked_z2_motor = state; } #endif #if ENABLED(BABYSTEPPING) @@ -267,12 +287,12 @@ class Stepper { // // Handle a triggered endstop // - static void endstop_triggered(AxisEnum axis); + static void endstop_triggered(const AxisEnum axis); // // Triggered position of an axis in mm (not core-savvy) // - static FORCE_INLINE float triggered_position_mm(AxisEnum axis) { + FORCE_INLINE static float triggered_position_mm(const AxisEnum axis) { return endstops_trigsteps[axis] * planner.steps_to_mm[axis]; } @@ -282,7 +302,7 @@ class Stepper { private: - static FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { + FORCE_INLINE static unsigned short calc_timer_interval(unsigned short step_rate) { unsigned short timer; NOMORE(step_rate, MAX_STEP_FREQUENCY); @@ -324,7 +344,7 @@ class Stepper { // Initialize the trapezoid generator from the current block. // Called whenever a new block begins. - static FORCE_INLINE void trapezoid_generator_reset() { + FORCE_INLINE static void trapezoid_generator_reset() { static int8_t last_extruder = -1; @@ -336,11 +356,11 @@ class Stepper { deceleration_time = 0; // step_rate to timer interval - OCR1A_nominal = calc_timer(current_block->nominal_rate); + OCR1A_nominal = calc_timer_interval(current_block->nominal_rate); // make a note of the number of step loops required at nominal speed step_loops_nominal = step_loops; acc_step_rate = current_block->initial_rate; - acceleration_time = calc_timer(acc_step_rate); + acceleration_time = calc_timer_interval(acc_step_rate); _NEXT_ISR(acceleration_time); #if ENABLED(LIN_ADVANCE) diff --git a/Marlin/stepper_dac.cpp b/Marlin/stepper_dac.cpp index 6ea8b83bce..f7161e3460 100644 --- a/Marlin/stepper_dac.cpp +++ b/Marlin/stepper_dac.cpp @@ -94,7 +94,7 @@ static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * (1.0 / (DAC_STEPPER_MAX)); } static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * (1.0 / (DAC_STEPPER_SENSE)); } - uint8_t dac_current_get_percent(AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); } + uint8_t dac_current_get_percent(const AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); } void dac_current_set_percents(const uint8_t pct[XYZE]) { LOOP_XYZE(i) dac_channel_pct[i] = pct[dac_order[i]]; mcp4728_setDrvPct(dac_channel_pct); diff --git a/Marlin/stepper_dac.h b/Marlin/stepper_dac.h index 5880350405..cf56050e72 100644 --- a/Marlin/stepper_dac.h +++ b/Marlin/stepper_dac.h @@ -51,7 +51,7 @@ void dac_current_percent(uint8_t channel, float val); void dac_current_raw(uint8_t channel, uint16_t val); void dac_print_values(); void dac_commit_eeprom(); -uint8_t dac_current_get_percent(AxisEnum axis); +uint8_t dac_current_get_percent(const AxisEnum axis); void dac_current_set_percents(const uint8_t pct[XYZE]); #endif // STEPPER_DAC_H diff --git a/Marlin/stepper_indirection.cpp b/Marlin/stepper_indirection.cpp index 9e9d3bf996..8811ed0979 100644 --- a/Marlin/stepper_indirection.cpp +++ b/Marlin/stepper_indirection.cpp @@ -129,6 +129,7 @@ #include #include + #include "planner.h" #include "enum.h" #define _TMC2130_DEFINE(ST) TMC2130Stepper stepper##ST(ST##_ENABLE_PIN, ST##_DIR_PIN, ST##_STEP_PIN, ST##_CS_PIN) @@ -171,16 +172,16 @@ // Use internal reference voltage for current calculations. This is the default. // Following values from Trinamic's spreadsheet with values for a NEMA17 (42BYGHW609) // https://www.trinamic.com/products/integrated-circuits/details/tmc2130/ - void tmc2130_init(TMC2130Stepper &st, const uint16_t microsteps, const uint32_t thrs, const float &spmm) { + void tmc2130_init(TMC2130Stepper &st, const uint16_t microsteps, const uint32_t thrs, const float spmm) { st.begin(); st.setCurrent(st.getCurrent(), R_SENSE, HOLD_MULTIPLIER); st.microsteps(microsteps); - st.blank_time(36); + st.blank_time(24); st.off_time(5); // Only enables the driver if used with stealthChop st.interpolate(INTERPOLATE); st.power_down_delay(128); // ~2s until driver lowers to hold current - st.hysterisis_start(0); // HSTRT = 1 - st.hysterisis_low(1); // HEND = -2 + st.hysterisis_start(3); + st.hysterisis_end(2); st.diag1_active_high(1); // For sensorless homing #if ENABLED(STEALTHCHOP) st.stealth_freq(1); // f_pwm = 2/683 f_clk @@ -189,61 +190,260 @@ st.stealth_amplitude(255); st.stealthChop(1); #if ENABLED(HYBRID_THRESHOLD) - st.stealth_max_speed(12650000UL*st.microsteps()/(256*thrs*spmm)); + st.stealth_max_speed(12650000UL*microsteps/(256*thrs*spmm)); + #else + UNUSED(thrs); + UNUSED(spmm); #endif #elif ENABLED(SENSORLESS_HOMING) st.coolstep_min_speed(1024UL * 1024UL - 1UL); #endif + st.GSTAT(); // Clear GSTAT } #define _TMC2130_INIT(ST, SPMM) tmc2130_init(stepper##ST, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM) void tmc2130_init() { - constexpr float steps_per_mm[] = DEFAULT_AXIS_STEPS_PER_UNIT; #if ENABLED(X_IS_TMC2130) - _TMC2130_INIT( X, steps_per_mm[X_AXIS]); - #if ENABLED(SENSORLESS_HOMING) - stepperX.sg_stall_value(X_HOMING_SENSITIVITY); - #endif + _TMC2130_INIT( X, planner.axis_steps_per_mm[X_AXIS]); #endif #if ENABLED(X2_IS_TMC2130) - _TMC2130_INIT(X2, steps_per_mm[X_AXIS]); + _TMC2130_INIT(X2, planner.axis_steps_per_mm[X_AXIS]); #endif #if ENABLED(Y_IS_TMC2130) - _TMC2130_INIT( Y, steps_per_mm[Y_AXIS]); - #if ENABLED(SENSORLESS_HOMING) - stepperY.sg_stall_value(Y_HOMING_SENSITIVITY); - #endif + _TMC2130_INIT( Y, planner.axis_steps_per_mm[Y_AXIS]); #endif #if ENABLED(Y2_IS_TMC2130) - _TMC2130_INIT(Y2, steps_per_mm[Y_AXIS]); + _TMC2130_INIT(Y2, planner.axis_steps_per_mm[Y_AXIS]); #endif #if ENABLED(Z_IS_TMC2130) - _TMC2130_INIT( Z, steps_per_mm[Z_AXIS]); + _TMC2130_INIT( Z, planner.axis_steps_per_mm[Z_AXIS]); #endif #if ENABLED(Z2_IS_TMC2130) - _TMC2130_INIT(Z2, steps_per_mm[Z_AXIS]); + _TMC2130_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]); #endif #if ENABLED(E0_IS_TMC2130) - _TMC2130_INIT(E0, steps_per_mm[E_AXIS]); + _TMC2130_INIT(E0, planner.axis_steps_per_mm[E_AXIS]); #endif #if ENABLED(E1_IS_TMC2130) - { constexpr int extruder = 1; _TMC2130_INIT(E1, steps_per_mm[E_AXIS_N]); } + { constexpr int extruder = 1; _TMC2130_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E2_IS_TMC2130) - { constexpr int extruder = 2; _TMC2130_INIT(E2, steps_per_mm[E_AXIS_N]); } + { constexpr int extruder = 2; _TMC2130_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E3_IS_TMC2130) - { constexpr int extruder = 3; _TMC2130_INIT(E3, steps_per_mm[E_AXIS_N]); } + { constexpr int extruder = 3; _TMC2130_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E4_IS_TMC2130) - { constexpr int extruder = 4; _TMC2130_INIT(E4, steps_per_mm[E_AXIS_N]); } + { constexpr int extruder = 4; _TMC2130_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); } #endif - TMC2130_ADV() } #endif // HAVE_TMC2130 +// +// TMC2208 Driver objects and inits +// +#if ENABLED(HAVE_TMC2208) + + #include + #include + #include + #include "planner.h" + + #define _TMC2208_DEFINE_HARDWARE(ST) TMC2208Stepper stepper##ST(&ST##_HARDWARE_SERIAL) + #define _TMC2208_DEFINE_SOFTWARE(ST) SoftwareSerial stepper##ST##_serial = SoftwareSerial(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN); \ + TMC2208Stepper stepper##ST(&stepper##ST##_serial, ST##_SERIAL_RX_PIN > -1) + + // Stepper objects of TMC2208 steppers used + #if ENABLED(X_IS_TMC2208) + #if defined(X_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(X); + #else + _TMC2208_DEFINE_SOFTWARE(X); + #endif + #endif + #if ENABLED(X2_IS_TMC2208) + #if defined(X2_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(X2); + #else + _TMC2208_DEFINE_SOFTWARE(X2); + #endif + #endif + #if ENABLED(Y_IS_TMC2208) + #if defined(Y_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(Y); + #else + _TMC2208_DEFINE_SOFTWARE(Y); + #endif + #endif + #if ENABLED(Y2_IS_TMC2208) + #if defined(Y2_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(Y2); + #else + _TMC2208_DEFINE_SOFTWARE(Y2); + #endif + #endif + #if ENABLED(Z_IS_TMC2208) + #if defined(Z_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(Z); + #else + _TMC2208_DEFINE_SOFTWARE(Z); + #endif + #endif + #if ENABLED(Z2_IS_TMC2208) + #if defined(Z2_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(Z2); + #else + _TMC2208_DEFINE_SOFTWARE(Z2); + #endif + #endif + #if ENABLED(E0_IS_TMC2208) + #if defined(E0_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(E0); + #else + _TMC2208_DEFINE_SOFTWARE(E0); + #endif + #endif + #if ENABLED(E1_IS_TMC2208) + #if defined(E1_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(E1); + #else + _TMC2208_DEFINE_SOFTWARE(E1); + #endif + #endif + #if ENABLED(E2_IS_TMC2208) + #if defined(E2_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(E2); + #else + _TMC2208_DEFINE_SOFTWARE(E2); + #endif + #endif + #if ENABLED(E3_IS_TMC2208) + #if defined(E3_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(E3); + #else + _TMC2208_DEFINE_SOFTWARE(E3); + #endif + #endif + #if ENABLED(E4_IS_TMC2208) + #if defined(E4_HARDWARE_SERIAL) + _TMC2208_DEFINE_HARDWARE(E4); + #else + _TMC2208_DEFINE_SOFTWARE(E4); + #endif + #endif + + void tmc2208_serial_begin() { + #if ENABLED(X_IS_TMC2208) && defined(X_HARDWARE_SERIAL) + X_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(X2_IS_TMC2208) && defined(X2_HARDWARE_SERIAL) + X2_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(Y_IS_TMC2208) && defined(Y_HARDWARE_SERIAL) + Y_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(Y2_IS_TMC2208) && defined(Y2_HARDWARE_SERIAL) + Y2_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(Z_IS_TMC2208) && defined(Z_HARDWARE_SERIAL) + Z_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(Z2_IS_TMC2208) && defined(Z2_HARDWARE_SERIAL) + Z2_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(E0_IS_TMC2208) && defined(E0_HARDWARE_SERIAL) + E0_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(E1_IS_TMC2208) && defined(E1_HARDWARE_SERIAL) + E1_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(E2_IS_TMC2208) && defined(E2_HARDWARE_SERIAL) + E2_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(E3_IS_TMC2208) && defined(E3_HARDWARE_SERIAL) + E3_HARDWARE_SERIAL.begin(250000); + #endif + #if ENABLED(E4_IS_TMC2208) && defined(E4_HARDWARE_SERIAL) + E4_HARDWARE_SERIAL.begin(250000); + #endif + } + + // Use internal reference voltage for current calculations. This is the default. + // Following values from Trinamic's spreadsheet with values for a NEMA17 (42BYGHW609) + void tmc2208_init(TMC2208Stepper &st, const uint16_t microsteps, const uint32_t thrs, const float spmm) { + st.pdn_disable(true); // Use UART + st.mstep_reg_select(true); // Select microsteps with UART + st.I_scale_analog(false); + st.rms_current(st.getCurrent(), HOLD_MULTIPLIER, R_SENSE); + st.microsteps(microsteps); + st.blank_time(24); + st.toff(5); + st.intpol(INTERPOLATE); + st.TPOWERDOWN(128); // ~2s until driver lowers to hold current + st.hysterisis_start(3); + st.hysterisis_end(2); + #if ENABLED(STEALTHCHOP) + st.pwm_lim(12); + st.pwm_reg(8); + st.pwm_autograd(1); + st.pwm_autoscale(1); + st.pwm_freq(1); + st.pwm_grad(14); + st.pwm_ofs(36); + st.en_spreadCycle(false); + #if ENABLED(HYBRID_THRESHOLD) + st.TPWMTHRS(12650000UL*microsteps/(256*thrs*spmm)); + #else + UNUSED(thrs); + UNUSED(spmm); + #endif + #else + st.en_spreadCycle(true); + #endif + st.GSTAT(0b111); // Clear + delay(200); + } + + #define _TMC2208_INIT(ST, SPMM) tmc2208_init(stepper##ST, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM) + + void tmc2208_init() { + #if ENABLED(X_IS_TMC2208) + _TMC2208_INIT(X, planner.axis_steps_per_mm[X_AXIS]); + #endif + #if ENABLED(X2_IS_TMC2208) + _TMC2208_INIT(X2, planner.axis_steps_per_mm[X_AXIS]); + #endif + #if ENABLED(Y_IS_TMC2208) + _TMC2208_INIT(Y, planner.axis_steps_per_mm[Y_AXIS]); + #endif + #if ENABLED(Y2_IS_TMC2208) + _TMC2208_INIT(Y2, planner.axis_steps_per_mm[Y_AXIS]); + #endif + #if ENABLED(Z_IS_TMC2208) + _TMC2208_INIT(Z, planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(Z2_IS_TMC2208) + _TMC2208_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(E0_IS_TMC2208) + _TMC2208_INIT(E0, planner.axis_steps_per_mm[E_AXIS]); + #endif + #if ENABLED(E1_IS_TMC2208) + { constexpr int extruder = 1; _TMC2208_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E2_IS_TMC2208) + { constexpr int extruder = 2; _TMC2208_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E3_IS_TMC2208) + { constexpr int extruder = 3; _TMC2208_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E4_IS_TMC2208) + { constexpr int extruder = 4; _TMC2208_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N]); } + #endif + } +#endif // HAVE_TMC2208 // // L6470 Driver objects and inits diff --git a/Marlin/stepper_indirection.h b/Marlin/stepper_indirection.h index 8b86246412..f24936d4d0 100644 --- a/Marlin/stepper_indirection.h +++ b/Marlin/stepper_indirection.h @@ -58,6 +58,12 @@ void tmc2130_init(); #endif +#if ENABLED(HAVE_TMC2208) + #include + void tmc2208_serial_begin(); + void tmc2208_init(); +#endif + // L6470 has STEP on normal pins, but DIR/ENABLE via SPI #if ENABLED(HAVE_L6470DRIVER) #include @@ -83,6 +89,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(X_IS_TMC2130) extern TMC2130Stepper stepperX; + #elif ENABLED(HAVE_TMC2208) && ENABLED(X_IS_TMC2208) + extern TMC2208Stepper stepperX; #endif #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN) #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE) @@ -114,6 +122,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(Y_IS_TMC2130) extern TMC2130Stepper stepperY; + #elif ENABLED(HAVE_TMC2208) && ENABLED(Y_IS_TMC2208) + extern TMC2208Stepper stepperY; #endif #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN) #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE) @@ -145,6 +155,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(Z_IS_TMC2130) extern TMC2130Stepper stepperZ; + #elif ENABLED(HAVE_TMC2208) && ENABLED(Z_IS_TMC2208) + extern TMC2208Stepper stepperZ; #endif #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN) #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE) @@ -177,6 +189,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(X2_IS_TMC2130) extern TMC2130Stepper stepperX2; + #elif ENABLED(HAVE_TMC2208) && ENABLED(X2_IS_TMC2208) + extern TMC2208Stepper stepperX2; #endif #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN) #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE) @@ -210,6 +224,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(Y2_IS_TMC2130) extern TMC2130Stepper stepperY2; + #elif ENABLED(HAVE_TMC2208) && ENABLED(Y2_IS_TMC2208) + extern TMC2208Stepper stepperY2; #endif #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN) #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE) @@ -243,6 +259,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(Z2_IS_TMC2130) extern TMC2130Stepper stepperZ2; + #elif ENABLED(HAVE_TMC2208) && ENABLED(Z2_IS_TMC2208) + extern TMC2208Stepper stepperZ2; #endif #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN) #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE) @@ -275,6 +293,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(E0_IS_TMC2130) extern TMC2130Stepper stepperE0; + #elif ENABLED(HAVE_TMC2208) && ENABLED(E0_IS_TMC2208) + extern TMC2208Stepper stepperE0; #endif #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN) #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE) @@ -306,6 +326,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(E1_IS_TMC2130) extern TMC2130Stepper stepperE1; + #elif ENABLED(HAVE_TMC2208) && ENABLED(E1_IS_TMC2208) + extern TMC2208Stepper stepperE1; #endif #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN) #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE) @@ -337,6 +359,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(E2_IS_TMC2130) extern TMC2130Stepper stepperE2; + #elif ENABLED(HAVE_TMC2208) && ENABLED(E2_IS_TMC2208) + extern TMC2208Stepper stepperE2; #endif #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN) #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE) @@ -368,6 +392,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(E3_IS_TMC2130) extern TMC2130Stepper stepperE3; + #elif ENABLED(HAVE_TMC2208) && ENABLED(E3_IS_TMC2208) + extern TMC2208Stepper stepperE3; #endif #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN) #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE) @@ -399,6 +425,8 @@ #else #if ENABLED(HAVE_TMC2130) && ENABLED(E4_IS_TMC2130) extern TMC2130Stepper stepperE4; + #elif ENABLED(HAVE_TMC2208) && ENABLED(E4_IS_TMC2208) + extern TMC2208Stepper stepperE4; #endif #define E4_ENABLE_INIT SET_OUTPUT(E4_ENABLE_PIN) #define E4_ENABLE_WRITE(STATE) WRITE(E4_ENABLE_PIN,STATE) @@ -429,6 +457,10 @@ #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(INVERT_E1_DIR); } } #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } } #endif +#elif ENABLED(MK2_MULTIPLEXER) // Even-numbered steppers are reversed + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) + #define NORM_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR) #elif EXTRUDERS > 4 #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); } } #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } } @@ -472,14 +504,8 @@ #endif #else #define E_STEP_WRITE(v) E0_STEP_WRITE(v) - #if ENABLED(MK2_MULTIPLEXER) - // Even-numbered steppers are reversed - #define NORM_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR) - #define REV_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR) - #else - #define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR) - #define REV_E_DIR() E0_DIR_WRITE(INVERT_E0_DIR) - #endif + #define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(INVERT_E0_DIR) #endif #endif // STEPPER_INDIRECTION_H diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index e2ea537841..750f08467f 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -32,7 +32,7 @@ #include "language.h" #if ENABLED(HEATER_0_USES_MAX6675) - #include "spi.h" + #include "MarlinSPI.h" #endif #if ENABLED(BABYSTEPPING) @@ -47,10 +47,6 @@ #include "watchdog.h" #endif -#ifdef K1 // Defined in Configuration.h in the PID settings - #define K2 (1.0-K1) -#endif - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) static void* heater_ttbl_map[2] = { (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE }; static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN }; @@ -215,36 +211,74 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], #if HAS_PID_HEATING - void Temperature::PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) { + /** + * PID Autotuning (M303) + * + * Alternately heat and cool the nozzle, observing its behavior to + * determine the best PID values to achieve a stable temperature. + */ + void Temperature::PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result/*=false*/) { float input = 0.0; int cycles = 0; bool heating = true; - millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms; + millis_t next_temp_ms = millis(), t1 = next_temp_ms, t2 = next_temp_ms; long t_high = 0, t_low = 0; long bias, d; - float Ku, Tu; - float workKp = 0, workKi = 0, workKd = 0; - float max = 0, min = 10000; + float Ku, Tu, + workKp = 0, workKi = 0, workKd = 0, + max = 0, min = 10000; - #if HAS_AUTO_FAN - next_auto_fan_check_ms = temp_ms + 2500UL; + #if WATCH_THE_BED || WATCH_HOTENDS + const float watch_temp_target = temp - + #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP) + (hotend < 0 ? (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1) : (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) + #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) + (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1) + #else + (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1) + #endif + ; + const int8_t watch_temp_period = + #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP) + hotend < 0 ? WATCH_BED_TEMP_PERIOD : WATCH_TEMP_PERIOD + #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) + WATCH_BED_TEMP_PERIOD + #else + WATCH_TEMP_PERIOD + #endif + ; + const int8_t watch_temp_increase = + #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP) + hotend < 0 ? WATCH_BED_TEMP_INCREASE : WATCH_TEMP_INCREASE + #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) + WATCH_BED_TEMP_INCREASE + #else + WATCH_TEMP_INCREASE + #endif + ; + millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL; + float next_watch_temp = 0.0; + bool heated = false; #endif - if (hotend >= - #if ENABLED(PIDTEMP) - HOTENDS - #else - 0 - #endif - || hotend < - #if ENABLED(PIDTEMPBED) - -1 - #else - 0 - #endif - ) { + #if HAS_AUTO_FAN + next_auto_fan_check_ms = next_temp_ms + 2500UL; + #endif + + #if ENABLED(PIDTEMP) + #define _TOP_HOTEND HOTENDS - 1 + #else + #define _TOP_HOTEND -1 + #endif + #if ENABLED(PIDTEMPBED) + #define _BOT_HOTEND -1 + #else + #define _BOT_HOTEND 0 + #endif + + if (!WITHIN(hotend, _BOT_HOTEND, _TOP_HOTEND)) { SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM); return; } @@ -269,7 +303,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], // PID Tuning loop while (wait_for_heatup) { - millis_t ms = millis(); + const millis_t ms = millis(); if (temp_meas_ready) { // temp sample ready updateTemperaturesFromRawValues(); @@ -330,7 +364,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], ; bias += (d * (t_high - t_low)) / (t_low + t_high); bias = constrain(bias, 20, max_pow - 20); - d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias; + d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias; SERIAL_PROTOCOLPAIR(MSG_BIAS, bias); SERIAL_PROTOCOLPAIR(MSG_D, d); @@ -384,21 +418,33 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], #define MAX_OVERSHOOT_PID_AUTOTUNE 20 if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) { SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH); - return; + break; } // Every 2 seconds... - if (ELAPSED(ms, temp_ms + 2000UL)) { + if (ELAPSED(ms, next_temp_ms)) { #if HAS_TEMP_HOTEND || HAS_TEMP_BED print_heaterstates(); SERIAL_EOL(); #endif - temp_ms = ms; + next_temp_ms = ms + 2000UL; + + #if WATCH_THE_BED || WATCH_HOTENDS + if (!heated && input > next_watch_temp) { + if (input > watch_temp_target) heated = true; + next_watch_temp = input + watch_temp_increase; + temp_change_ms = ms + watch_temp_period * 1000UL; + } + else if (!heated && ELAPSED(ms, temp_change_ms)) + _temp_error(hotend, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + else if (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE) + _temp_error(hotend, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY)); + #endif } // every 2 seconds - // Over 2 minutes? - if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) { + // Timeout after 20 minutes since the last undershoot/overshoot cycle + if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) { SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT); - return; + break; } if (cycles > ncycles) { SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED); @@ -422,7 +468,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], bedKp = workKp; \ bedKi = scalePID_i(workKi); \ bedKd = scalePID_d(workKd); \ - updatePID(); }while(0) + }while(0) #define _SET_EXTRUDER_PID() do { \ PID_PARAM(Kp, hotend) = workKp; \ @@ -447,7 +493,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], } lcd_update(); } - if (!wait_for_heatup) disable_all_heaters(); + disable_all_heaters(); } #endif // HAS_PID_HEATING @@ -458,14 +504,6 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], Temperature::Temperature() { } -void Temperature::updatePID() { - #if ENABLED(PIDTEMP) - #if ENABLED(PID_EXTRUSION_SCALING) - last_e_position = 0; - #endif - #endif -} - int Temperature::getHeaterPower(int heater) { return heater < 0 ? soft_pwm_amount_bed : soft_pwm_amount[heater]; } @@ -557,7 +595,7 @@ float Temperature::get_pid_output(const int8_t e) { #if ENABLED(PIDTEMP) #if DISABLED(PID_OPENLOOP) pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; - dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX]; + dTerm[HOTEND_INDEX] = PID_K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + PID_K1 * dTerm[HOTEND_INDEX]; temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; #if HEATER_IDLE_HANDLER if (heater_idle_timeout_exceeded[HOTEND_INDEX]) { @@ -654,7 +692,7 @@ float Temperature::get_pid_output(const int8_t e) { temp_iState_bed += pid_error_bed; iTerm_bed = bedKi * temp_iState_bed; - dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed; + dTerm_bed = PID_K2 * bedKd * (current_temperature_bed - temp_dState_bed) + PID_K1 * dTerm_bed; temp_dState_bed = current_temperature_bed; pid_output = pTerm_bed + iTerm_bed - dTerm_bed; @@ -698,17 +736,6 @@ float Temperature::get_pid_output(const int8_t e) { * - Apply filament width to the extrusion rate (may move) * - Update the heated bed PID output value */ - -/** - * The following line SOMETIMES results in the dreaded "unable to find a register to spill in class 'POINTER_REGS'" - * compile error. - * thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); - * - * This is due to a bug in the C++ compiler used by the Arduino IDE from 1.6.10 to at least 1.8.1. - * - * The work around is to add the compiler flag "__attribute__((__optimize__("O2")))" to the declaration for manage_heater() - */ -//void Temperature::manage_heater() __attribute__((__optimize__("O2"))); void Temperature::manage_heater() { if (!temp_meas_ready) return; @@ -763,17 +790,16 @@ void Temperature::manage_heater() { } #endif - // Control the extruder rate based on the width sensor #if ENABLED(FILAMENT_WIDTH_SENSOR) + /** + * Filament Width Sensor dynamically sets the volumetric multiplier + * based on a delayed measurement of the filament diameter. + */ if (filament_sensor) { meas_shift_index = filwidth_delay_index[0] - meas_delay_cm; if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY); - - // Get the delayed info and add 100 to reconstitute to a percent of - // the nominal filament diameter then square it to get an area - const float vmroot = measurement_delay[meas_shift_index] * 0.01 + 1.0; - volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vmroot <= 0.1 ? 0.01 : sq(vmroot); + planner.calculate_volumetric_for_width_sensor(measurement_delay[meas_shift_index]); } #endif // FILAMENT_WIDTH_SENSOR @@ -848,7 +874,7 @@ void Temperature::manage_heater() { // Derived from RepRap FiveD extruder::getTemperature() // For hot end temperature measurement. -float Temperature::analog2temp(int raw, uint8_t e) { +float Temperature::analog2temp(const int raw, const uint8_t e) { #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) if (e > HOTENDS) #else @@ -889,39 +915,41 @@ float Temperature::analog2temp(int raw, uint8_t e) { return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; } -// Derived from RepRap FiveD extruder::getTemperature() -// For bed temperature measurement. -float Temperature::analog2tempBed(const int raw) { - #if ENABLED(BED_USES_THERMISTOR) - float celsius = 0; - byte i; +#if HAS_TEMP_BED + // Derived from RepRap FiveD extruder::getTemperature() + // For bed temperature measurement. + float Temperature::analog2tempBed(const int raw) { + #if ENABLED(BED_USES_THERMISTOR) + float celsius = 0; + byte i; - for (i = 1; i < BEDTEMPTABLE_LEN; i++) { - if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { - celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + - (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * - (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / - (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); - break; + for (i = 1; i < BEDTEMPTABLE_LEN; i++) { + if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { + celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + + (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * + (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / + (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); + break; + } } - } - // Overflow: Set to last value in the table - if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); + // Overflow: Set to last value in the table + if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); - return celsius; + return celsius; - #elif defined(BED_USES_AD595) + #elif defined(BED_USES_AD595) - return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; - #else + #else - UNUSED(raw); - return 0; + UNUSED(raw); + return 0; - #endif -} + #endif + } +#endif // HAS_TEMP_BED /** * Get the raw values into the actual temperatures. @@ -935,7 +963,9 @@ void Temperature::updateTemperaturesFromRawValues() { #endif HOTEND_LOOP() current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); - current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); + #if HAS_TEMP_BED + current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); + #endif #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) redundant_temperature = Temperature::analog2temp(redundant_temperature_raw, 1); #endif @@ -959,15 +989,20 @@ void Temperature::updateTemperaturesFromRawValues() { // Convert raw Filament Width to millimeters float Temperature::analog2widthFil() { return current_raw_filwidth * 5.0 * (1.0 / 16383.0); - //return current_raw_filwidth; } - // Convert raw Filament Width to a ratio - int Temperature::widthFil_to_size_ratio() { - float temp = filament_width_meas; - if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal; //assume sensor cut out - else NOMORE(temp, MEASURED_UPPER_LIMIT); - return filament_width_nominal / temp * 100; + /** + * Convert Filament Width (mm) to a simple ratio + * and reduce to an 8 bit value. + * + * A nominal width of 1.75 and measured width of 1.73 + * gives (100 * 1.75 / 1.73) for a ratio of 101 and + * a return value of 1. + */ + int8_t Temperature::widthFil_to_size_ratio() { + if (FABS(filament_width_nominal - filament_width_meas) <= FILWIDTH_ERROR_MARGIN) + return int(100.0 * filament_width_nominal / filament_width_meas) - 100; + return 0; } #endif @@ -1203,24 +1238,26 @@ void Temperature::init() { #endif // HOTENDS > 2 #endif // HOTENDS > 1 - #ifdef BED_MINTEMP - while (analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { - #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP - bed_minttemp_raw += OVERSAMPLENR; - #else - bed_minttemp_raw -= OVERSAMPLENR; - #endif - } - #endif // BED_MINTEMP - #ifdef BED_MAXTEMP - while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { - #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP - bed_maxttemp_raw -= OVERSAMPLENR; - #else - bed_maxttemp_raw += OVERSAMPLENR; - #endif - } - #endif // BED_MAXTEMP + #if HAS_TEMP_BED + #ifdef BED_MINTEMP + while (analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_minttemp_raw += OVERSAMPLENR; + #else + bed_minttemp_raw -= OVERSAMPLENR; + #endif + } + #endif // BED_MINTEMP + #ifdef BED_MAXTEMP + while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_maxttemp_raw -= OVERSAMPLENR; + #else + bed_maxttemp_raw += OVERSAMPLENR; + #endif + } + #endif // BED_MAXTEMP + #endif //HAS_TEMP_BED #if ENABLED(PROBING_HEATERS_OFF) paused = false; @@ -1233,7 +1270,7 @@ void Temperature::init() { * their target temperature by a configurable margin. * This is called when the temperature is set. (M104, M109) */ - void Temperature::start_watching_heater(uint8_t e) { + void Temperature::start_watching_heater(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -1274,7 +1311,7 @@ void Temperature::init() { millis_t Temperature::thermal_runaway_bed_timer; #endif - void Temperature::thermal_runaway_protection(Temperature::TRState* state, millis_t* timer, float current, float target, int heater_id, int period_seconds, int hysteresis_degc) { + void Temperature::thermal_runaway_protection(Temperature::TRState * const state, millis_t * const timer, const float current, const float target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; @@ -1703,15 +1740,15 @@ void Temperature::isr() { #if ENABLED(FAN_SOFT_PWM) #if HAS_FAN0 - soft_pwm_count_fan[0] = (soft_pwm_count_fan[0] & pwm_mask) + soft_pwm_amount_fan[0] >> 1; + soft_pwm_count_fan[0] = (soft_pwm_count_fan[0] & pwm_mask) + (soft_pwm_amount_fan[0] >> 1); WRITE_FAN(soft_pwm_count_fan[0] > pwm_mask ? HIGH : LOW); #endif #if HAS_FAN1 - soft_pwm_count_fan[1] = (soft_pwm_count_fan[1] & pwm_mask) + soft_pwm_amount_fan[1] >> 1; + soft_pwm_count_fan[1] = (soft_pwm_count_fan[1] & pwm_mask) + (soft_pwm_amount_fan[1] >> 1); WRITE_FAN1(soft_pwm_count_fan[1] > pwm_mask ? HIGH : LOW); #endif #if HAS_FAN2 - soft_pwm_count_fan[2] = (soft_pwm_count_fan[2] & pwm_mask) + soft_pwm_amount_fan[2] >> 1; + soft_pwm_count_fan[2] = (soft_pwm_count_fan[2] & pwm_mask) + (soft_pwm_amount_fan[2] >> 1); WRITE_FAN2(soft_pwm_count_fan[2] > pwm_mask ? HIGH : LOW); #endif #endif @@ -1771,8 +1808,8 @@ void Temperature::isr() { // Macros for Slow PWM timer logic #define _SLOW_PWM_ROUTINE(NR, src) \ - soft_pwm_ ##NR = src; \ - if (soft_pwm_ ##NR > 0) { \ + soft_pwm_count_ ##NR = src; \ + if (soft_pwm_count_ ##NR > 0) { \ if (state_timer_heater_ ##NR == 0) { \ if (state_heater_ ##NR == 0) state_timer_heater_ ##NR = MIN_STATE_TIME; \ state_heater_ ##NR = 1; \ @@ -1789,7 +1826,7 @@ void Temperature::isr() { #define SLOW_PWM_ROUTINE(n) _SLOW_PWM_ROUTINE(n, soft_pwm_amount[n]) #define PWM_OFF_ROUTINE(NR) \ - if (soft_pwm_ ##NR < slow_pwm_count) { \ + if (soft_pwm_count_ ##NR < slow_pwm_count) { \ if (state_timer_heater_ ##NR == 0) { \ if (state_heater_ ##NR == 1) state_timer_heater_ ##NR = MIN_STATE_TIME; \ state_heater_ ##NR = 0; \ @@ -2067,8 +2104,15 @@ void Temperature::isr() { for (uint8_t e = 0; e < COUNT(temp_dir); e++) { const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir; - if (rawtemp > maxttemp_raw[e] * tdir && target_temperature[e] > 0) max_temp_error(e); - if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && target_temperature[e] > 0) { + const bool heater_on = 0 < + #if ENABLED(PIDTEMP) + soft_pwm_amount[e] + #else + target_temperature[e] + #endif + ; + if (rawtemp > maxttemp_raw[e] * tdir && heater_on) max_temp_error(e); + if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) { #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) #endif @@ -2086,14 +2130,22 @@ void Temperature::isr() { #else #define GEBED >= #endif - if (current_temperature_bed_raw GEBED bed_maxttemp_raw && target_temperature_bed > 0) max_temp_error(-1); - if (bed_minttemp_raw GEBED current_temperature_bed_raw && target_temperature_bed > 0) min_temp_error(-1); + const bool bed_on = 0 < + #if ENABLED(PIDTEMPBED) + soft_pwm_amount_bed + #else + target_temperature_bed + #endif + ; + if (current_temperature_bed_raw GEBED bed_maxttemp_raw && bed_on) max_temp_error(-1); + if (bed_minttemp_raw GEBED current_temperature_bed_raw && bed_on) min_temp_error(-1); #endif } // temp_count >= OVERSAMPLENR // Go to the next state, up to SensorsReady - adc_sensor_state = (ADCSensorState)((int(adc_sensor_state) + 1) % int(StartupDelay)); + adc_sensor_state = (ADCSensorState)(int(adc_sensor_state) + 1); + if (adc_sensor_state > SensorsReady) adc_sensor_state = (ADCSensorState)0; #if ENABLED(BABYSTEPPING) LOOP_XYZ(axis) { @@ -2131,3 +2183,95 @@ void Temperature::isr() { in_temp_isr = false; SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR } + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + + void print_heater_state(const float &c, const float &t, + #if ENABLED(SHOW_TEMP_ADC_VALUES) + const float r, + #endif + const int8_t e=-2 + ) { + #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 + UNUSED(e); + #endif + + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLCHAR( + #if HAS_TEMP_BED && HAS_TEMP_HOTEND + e == -1 ? 'B' : 'T' + #elif HAS_TEMP_HOTEND + 'T' + #else + 'B' + #endif + ); + #if HOTENDS > 1 + if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); + #endif + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(c); + SERIAL_PROTOCOLPAIR(" /" , t); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); + SERIAL_PROTOCOLCHAR(')'); + #endif + } + + extern uint8_t target_extruder; + + void Temperature::print_heaterstates() { + #if HAS_TEMP_HOTEND + print_heater_state(degHotend(target_extruder), degTargetHotend(target_extruder) + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawHotendTemp(target_extruder) + #endif + ); + #endif + #if HAS_TEMP_BED + print_heater_state(degBed(), degTargetBed() + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawBedTemp() + #endif + , -1 // BED + ); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e) + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawHotendTemp(e) + #endif + , e + ); + #endif + SERIAL_PROTOCOLPGM(" @:"); + SERIAL_PROTOCOL(getHeaterPower(target_extruder)); + #if HAS_TEMP_BED + SERIAL_PROTOCOLPGM(" B@:"); + SERIAL_PROTOCOL(getHeaterPower(-1)); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() { + SERIAL_PROTOCOLPAIR(" @", e); + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(getHeaterPower(e)); + } + #endif + } + + #if ENABLED(AUTO_REPORT_TEMPERATURES) + + uint8_t Temperature::auto_report_temp_interval; + millis_t Temperature::next_temp_report_ms; + + void Temperature::auto_report_temperatures() { + if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) { + next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; + print_heaterstates(); + SERIAL_EOL(); + } + } + + #endif // AUTO_REPORT_TEMPERATURES + +#endif // HAS_TEMP_HOTEND || HAS_TEMP_BED diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 6ce644d88e..95db0f6a1b 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -96,6 +96,17 @@ enum ADCSensorState { #define ACTUAL_ADC_SAMPLES max(int(MIN_ADC_ISR_LOOPS), int(SensorsReady)) +#if HAS_PID_HEATING + #define PID_K2 (1.0-PID_K1) + #define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (F_CPU / 64.0 / 256.0)) + + // Apply the scale factors to the PID values + #define scalePID_i(i) ( (i) * PID_dT ) + #define unscalePID_i(i) ( (i) / PID_dT ) + #define scalePID_d(d) ( (d) / PID_dT ) + #define unscalePID_d(d) ( (d) * PID_dT ) +#endif + #if !HAS_HEATER_BED constexpr int16_t target_temperature_bed = 0; #endif @@ -124,10 +135,6 @@ class Temperature { soft_pwm_count_fan[FAN_COUNT]; #endif - #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) - #define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (F_CPU / 64.0 / 256.0)) - #endif - #if ENABLED(PIDTEMP) #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 @@ -148,12 +155,6 @@ class Temperature { #endif // PID_PARAMS_PER_HOTEND - // Apply the scale factors to the PID values - #define scalePID_i(i) ( (i) * PID_dT ) - #define unscalePID_i(i) ( (i) / PID_dT ) - #define scalePID_d(d) ( (d) / PID_dT ) - #define unscalePID_d(d) ( (d) * PID_dT ) - #endif #if ENABLED(PIDTEMPBED) @@ -292,8 +293,11 @@ class Temperature { /** * Static (class) methods */ - static float analog2temp(int raw, uint8_t e); - static float analog2tempBed(int raw); + static float analog2temp(const int raw, const uint8_t e); + + #if HAS_TEMP_BED + static float analog2tempBed(const int raw); + #endif /** * Called from the Temperature ISR @@ -332,8 +336,8 @@ class Temperature { #endif #if ENABLED(FILAMENT_WIDTH_SENSOR) - static float analog2widthFil(); // Convert raw Filament Width to millimeters - static int widthFil_to_size_ratio(); // Convert raw Filament Width to an extrusion ratio + static float analog2widthFil(); // Convert raw Filament Width to millimeters + static int8_t widthFil_to_size_ratio(); // Convert Filament Width (mm) to an extrusion ratio #endif @@ -369,14 +373,14 @@ class Temperature { static int16_t degTargetBed() { return target_temperature_bed; } #if WATCH_HOTENDS - static void start_watching_heater(uint8_t e = 0); + static void start_watching_heater(const uint8_t e = 0); #endif #if WATCH_THE_BED static void start_watching_bed(); #endif - static void setTargetHotend(const int16_t celsius, uint8_t e) { + static void setTargetHotend(const int16_t celsius, const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -437,17 +441,24 @@ class Temperature { * Perform auto-tuning for hotend or bed in response to M303 */ #if HAS_PID_HEATING - static void PID_autotune(float temp, int hotend, int ncycles, bool set_result=false); - #endif + static void PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result=false); - /** - * Update the temp manager when PID values change - */ - static void updatePID(); + /** + * Update the temp manager when PID values change + */ + #if ENABLED(PIDTEMP) + FORCE_INLINE static void updatePID() { + #if ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + } + #endif + + #endif #if ENABLED(BABYSTEPPING) - static void babystep_axis(const AxisEnum axis, const int distance) { + static void babystep_axis(const AxisEnum axis, const int16_t distance) { if (axis_known_position[axis]) { #if IS_CORE #if ENABLED(BABYSTEP_XY) @@ -531,6 +542,20 @@ class Temperature { #endif #endif + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + static void print_heaterstates(); + #if ENABLED(AUTO_REPORT_TEMPERATURES) + static uint8_t auto_report_temp_interval; + static millis_t next_temp_report_ms; + static void auto_report_temperatures(void); + FORCE_INLINE void set_auto_report_interval(uint8_t v) { + NOMORE(v, 60); + auto_report_temp_interval = v; + next_temp_report_ms = millis() + 1000UL * v; + } + #endif + #endif + private: static void set_current_temp_raw(); @@ -557,7 +582,7 @@ class Temperature { typedef enum TRState { TRInactive, TRFirstHeating, TRStable, TRRunaway } TRstate; - static void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); + static void thermal_runaway_protection(TRState * const state, millis_t * const timer, const float current, const float target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); #if ENABLED(THERMAL_PROTECTION_HOTENDS) static TRState thermal_runaway_state_machine[HOTENDS]; diff --git a/Marlin/thermistortable_1.h b/Marlin/thermistortable_1.h index b1a91b5e5d..c3395a5aa9 100644 --- a/Marlin/thermistortable_1.h +++ b/Marlin/thermistortable_1.h @@ -22,68 +22,68 @@ // 100k bed thermistor const short temptable_1[][2] PROGMEM = { - { 23 * OVERSAMPLENR, 300 }, - { 25 * OVERSAMPLENR, 295 }, - { 27 * OVERSAMPLENR, 290 }, - { 28 * OVERSAMPLENR, 285 }, - { 31 * OVERSAMPLENR, 280 }, - { 33 * OVERSAMPLENR, 275 }, - { 35 * OVERSAMPLENR, 270 }, - { 38 * OVERSAMPLENR, 265 }, - { 41 * OVERSAMPLENR, 260 }, - { 44 * OVERSAMPLENR, 255 }, - { 48 * OVERSAMPLENR, 250 }, - { 52 * OVERSAMPLENR, 245 }, - { 56 * OVERSAMPLENR, 240 }, - { 61 * OVERSAMPLENR, 235 }, - { 66 * OVERSAMPLENR, 230 }, - { 71 * OVERSAMPLENR, 225 }, - { 78 * OVERSAMPLENR, 220 }, - { 84 * OVERSAMPLENR, 215 }, - { 92 * OVERSAMPLENR, 210 }, - { 100 * OVERSAMPLENR, 205 }, - { 109 * OVERSAMPLENR, 200 }, - { 120 * OVERSAMPLENR, 195 }, - { 131 * OVERSAMPLENR, 190 }, - { 143 * OVERSAMPLENR, 185 }, - { 156 * OVERSAMPLENR, 180 }, - { 171 * OVERSAMPLENR, 175 }, - { 187 * OVERSAMPLENR, 170 }, - { 205 * OVERSAMPLENR, 165 }, - { 224 * OVERSAMPLENR, 160 }, - { 245 * OVERSAMPLENR, 155 }, - { 268 * OVERSAMPLENR, 150 }, - { 293 * OVERSAMPLENR, 145 }, - { 320 * OVERSAMPLENR, 140 }, - { 348 * OVERSAMPLENR, 135 }, - { 379 * OVERSAMPLENR, 130 }, - { 411 * OVERSAMPLENR, 125 }, - { 445 * OVERSAMPLENR, 120 }, - { 480 * OVERSAMPLENR, 115 }, - { 516 * OVERSAMPLENR, 110 }, - { 553 * OVERSAMPLENR, 105 }, - { 591 * OVERSAMPLENR, 100 }, - { 628 * OVERSAMPLENR, 95 }, - { 665 * OVERSAMPLENR, 90 }, - { 702 * OVERSAMPLENR, 85 }, - { 737 * OVERSAMPLENR, 80 }, - { 770 * OVERSAMPLENR, 75 }, - { 801 * OVERSAMPLENR, 70 }, - { 830 * OVERSAMPLENR, 65 }, - { 857 * OVERSAMPLENR, 60 }, - { 881 * OVERSAMPLENR, 55 }, - { 903 * OVERSAMPLENR, 50 }, - { 922 * OVERSAMPLENR, 45 }, - { 939 * OVERSAMPLENR, 40 }, - { 954 * OVERSAMPLENR, 35 }, - { 966 * OVERSAMPLENR, 30 }, - { 977 * OVERSAMPLENR, 25 }, - { 985 * OVERSAMPLENR, 20 }, - { 993 * OVERSAMPLENR, 15 }, - { 999 * OVERSAMPLENR, 10 }, - { 1004 * OVERSAMPLENR, 5 }, - { 1008 * OVERSAMPLENR, 0 }, - { 1012 * OVERSAMPLENR, -5 }, - { 1016 * OVERSAMPLENR, -10 }, - { 1020 * OVERSAMPLENR, -15 } + { OV( 23), 300 }, + { OV( 25), 295 }, + { OV( 27), 290 }, + { OV( 28), 285 }, + { OV( 31), 280 }, + { OV( 33), 275 }, + { OV( 35), 270 }, + { OV( 38), 265 }, + { OV( 41), 260 }, + { OV( 44), 255 }, + { OV( 48), 250 }, + { OV( 52), 245 }, + { OV( 56), 240 }, + { OV( 61), 235 }, + { OV( 66), 230 }, + { OV( 71), 225 }, + { OV( 78), 220 }, + { OV( 84), 215 }, + { OV( 92), 210 }, + { OV( 100), 205 }, + { OV( 109), 200 }, + { OV( 120), 195 }, + { OV( 131), 190 }, + { OV( 143), 185 }, + { OV( 156), 180 }, + { OV( 171), 175 }, + { OV( 187), 170 }, + { OV( 205), 165 }, + { OV( 224), 160 }, + { OV( 245), 155 }, + { OV( 268), 150 }, + { OV( 293), 145 }, + { OV( 320), 140 }, + { OV( 348), 135 }, + { OV( 379), 130 }, + { OV( 411), 125 }, + { OV( 445), 120 }, + { OV( 480), 115 }, + { OV( 516), 110 }, + { OV( 553), 105 }, + { OV( 591), 100 }, + { OV( 628), 95 }, + { OV( 665), 90 }, + { OV( 702), 85 }, + { OV( 737), 80 }, + { OV( 770), 75 }, + { OV( 801), 70 }, + { OV( 830), 65 }, + { OV( 857), 60 }, + { OV( 881), 55 }, + { OV( 903), 50 }, + { OV( 922), 45 }, + { OV( 939), 40 }, + { OV( 954), 35 }, + { OV( 966), 30 }, + { OV( 977), 25 }, + { OV( 985), 20 }, + { OV( 993), 15 }, + { OV( 999), 10 }, + { OV(1004), 5 }, + { OV(1008), 0 }, + { OV(1012), -5 }, + { OV(1016), -10 }, + { OV(1020), -15 } }; diff --git a/Marlin/thermistortable_10.h b/Marlin/thermistortable_10.h index a031648a9d..2a49d6b144 100644 --- a/Marlin/thermistortable_10.h +++ b/Marlin/thermistortable_10.h @@ -22,35 +22,35 @@ // 100k RS thermistor 198-961 (4.7k pullup) const short temptable_10[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 929 }, - { 36 * OVERSAMPLENR, 299 }, - { 71 * OVERSAMPLENR, 246 }, - { 106 * OVERSAMPLENR, 217 }, - { 141 * OVERSAMPLENR, 198 }, - { 176 * OVERSAMPLENR, 184 }, - { 211 * OVERSAMPLENR, 173 }, - { 246 * OVERSAMPLENR, 163 }, - { 281 * OVERSAMPLENR, 154 }, - { 316 * OVERSAMPLENR, 147 }, - { 351 * OVERSAMPLENR, 140 }, - { 386 * OVERSAMPLENR, 134 }, - { 421 * OVERSAMPLENR, 128 }, - { 456 * OVERSAMPLENR, 122 }, - { 491 * OVERSAMPLENR, 117 }, - { 526 * OVERSAMPLENR, 112 }, - { 561 * OVERSAMPLENR, 107 }, - { 596 * OVERSAMPLENR, 102 }, - { 631 * OVERSAMPLENR, 97 }, - { 666 * OVERSAMPLENR, 91 }, - { 701 * OVERSAMPLENR, 86 }, - { 736 * OVERSAMPLENR, 81 }, - { 771 * OVERSAMPLENR, 76 }, - { 806 * OVERSAMPLENR, 70 }, - { 841 * OVERSAMPLENR, 63 }, - { 876 * OVERSAMPLENR, 56 }, - { 911 * OVERSAMPLENR, 48 }, - { 946 * OVERSAMPLENR, 38 }, - { 981 * OVERSAMPLENR, 23 }, - { 1005 * OVERSAMPLENR, 5 }, - { 1016 * OVERSAMPLENR, 0 } + { OV( 1), 929 }, + { OV( 36), 299 }, + { OV( 71), 246 }, + { OV( 106), 217 }, + { OV( 141), 198 }, + { OV( 176), 184 }, + { OV( 211), 173 }, + { OV( 246), 163 }, + { OV( 281), 154 }, + { OV( 316), 147 }, + { OV( 351), 140 }, + { OV( 386), 134 }, + { OV( 421), 128 }, + { OV( 456), 122 }, + { OV( 491), 117 }, + { OV( 526), 112 }, + { OV( 561), 107 }, + { OV( 596), 102 }, + { OV( 631), 97 }, + { OV( 666), 91 }, + { OV( 701), 86 }, + { OV( 736), 81 }, + { OV( 771), 76 }, + { OV( 806), 70 }, + { OV( 841), 63 }, + { OV( 876), 56 }, + { OV( 911), 48 }, + { OV( 946), 38 }, + { OV( 981), 23 }, + { OV(1005), 5 }, + { OV(1016), 0 } }; diff --git a/Marlin/thermistortable_11.h b/Marlin/thermistortable_11.h index f0f2697359..cc5715b78e 100644 --- a/Marlin/thermistortable_11.h +++ b/Marlin/thermistortable_11.h @@ -22,54 +22,54 @@ // QU-BD silicone bed QWG-104F-3950 thermistor const short temptable_11[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 938 }, - { 31 * OVERSAMPLENR, 314 }, - { 41 * OVERSAMPLENR, 290 }, - { 51 * OVERSAMPLENR, 272 }, - { 61 * OVERSAMPLENR, 258 }, - { 71 * OVERSAMPLENR, 247 }, - { 81 * OVERSAMPLENR, 237 }, - { 91 * OVERSAMPLENR, 229 }, - { 101 * OVERSAMPLENR, 221 }, - { 111 * OVERSAMPLENR, 215 }, - { 121 * OVERSAMPLENR, 209 }, - { 131 * OVERSAMPLENR, 204 }, - { 141 * OVERSAMPLENR, 199 }, - { 151 * OVERSAMPLENR, 195 }, - { 161 * OVERSAMPLENR, 190 }, - { 171 * OVERSAMPLENR, 187 }, - { 181 * OVERSAMPLENR, 183 }, - { 191 * OVERSAMPLENR, 179 }, - { 201 * OVERSAMPLENR, 176 }, - { 221 * OVERSAMPLENR, 170 }, - { 241 * OVERSAMPLENR, 165 }, - { 261 * OVERSAMPLENR, 160 }, - { 281 * OVERSAMPLENR, 155 }, - { 301 * OVERSAMPLENR, 150 }, - { 331 * OVERSAMPLENR, 144 }, - { 361 * OVERSAMPLENR, 139 }, - { 391 * OVERSAMPLENR, 133 }, - { 421 * OVERSAMPLENR, 128 }, - { 451 * OVERSAMPLENR, 123 }, - { 491 * OVERSAMPLENR, 117 }, - { 531 * OVERSAMPLENR, 111 }, - { 571 * OVERSAMPLENR, 105 }, - { 611 * OVERSAMPLENR, 100 }, - { 641 * OVERSAMPLENR, 95 }, - { 681 * OVERSAMPLENR, 90 }, - { 711 * OVERSAMPLENR, 85 }, - { 751 * OVERSAMPLENR, 79 }, - { 791 * OVERSAMPLENR, 72 }, - { 811 * OVERSAMPLENR, 69 }, - { 831 * OVERSAMPLENR, 65 }, - { 871 * OVERSAMPLENR, 57 }, - { 881 * OVERSAMPLENR, 55 }, - { 901 * OVERSAMPLENR, 51 }, - { 921 * OVERSAMPLENR, 45 }, - { 941 * OVERSAMPLENR, 39 }, - { 971 * OVERSAMPLENR, 28 }, - { 981 * OVERSAMPLENR, 23 }, - { 991 * OVERSAMPLENR, 17 }, - { 1001 * OVERSAMPLENR, 9 }, - { 1021 * OVERSAMPLENR, -27 } + { OV( 1), 938 }, + { OV( 31), 314 }, + { OV( 41), 290 }, + { OV( 51), 272 }, + { OV( 61), 258 }, + { OV( 71), 247 }, + { OV( 81), 237 }, + { OV( 91), 229 }, + { OV( 101), 221 }, + { OV( 111), 215 }, + { OV( 121), 209 }, + { OV( 131), 204 }, + { OV( 141), 199 }, + { OV( 151), 195 }, + { OV( 161), 190 }, + { OV( 171), 187 }, + { OV( 181), 183 }, + { OV( 191), 179 }, + { OV( 201), 176 }, + { OV( 221), 170 }, + { OV( 241), 165 }, + { OV( 261), 160 }, + { OV( 281), 155 }, + { OV( 301), 150 }, + { OV( 331), 144 }, + { OV( 361), 139 }, + { OV( 391), 133 }, + { OV( 421), 128 }, + { OV( 451), 123 }, + { OV( 491), 117 }, + { OV( 531), 111 }, + { OV( 571), 105 }, + { OV( 611), 100 }, + { OV( 641), 95 }, + { OV( 681), 90 }, + { OV( 711), 85 }, + { OV( 751), 79 }, + { OV( 791), 72 }, + { OV( 811), 69 }, + { OV( 831), 65 }, + { OV( 871), 57 }, + { OV( 881), 55 }, + { OV( 901), 51 }, + { OV( 921), 45 }, + { OV( 941), 39 }, + { OV( 971), 28 }, + { OV( 981), 23 }, + { OV( 991), 17 }, + { OV(1001), 9 }, + { OV(1021), -27 } }; diff --git a/Marlin/thermistortable_12.h b/Marlin/thermistortable_12.h index 802c1d37d3..aff539e2ce 100644 --- a/Marlin/thermistortable_12.h +++ b/Marlin/thermistortable_12.h @@ -22,34 +22,34 @@ // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) const short temptable_12[][2] PROGMEM = { - { 35 * OVERSAMPLENR, 180 }, // top rating 180C - { 211 * OVERSAMPLENR, 140 }, - { 233 * OVERSAMPLENR, 135 }, - { 261 * OVERSAMPLENR, 130 }, - { 290 * OVERSAMPLENR, 125 }, - { 328 * OVERSAMPLENR, 120 }, - { 362 * OVERSAMPLENR, 115 }, - { 406 * OVERSAMPLENR, 110 }, - { 446 * OVERSAMPLENR, 105 }, - { 496 * OVERSAMPLENR, 100 }, - { 539 * OVERSAMPLENR, 95 }, - { 585 * OVERSAMPLENR, 90 }, - { 629 * OVERSAMPLENR, 85 }, - { 675 * OVERSAMPLENR, 80 }, - { 718 * OVERSAMPLENR, 75 }, - { 758 * OVERSAMPLENR, 70 }, - { 793 * OVERSAMPLENR, 65 }, - { 822 * OVERSAMPLENR, 60 }, - { 841 * OVERSAMPLENR, 55 }, - { 875 * OVERSAMPLENR, 50 }, - { 899 * OVERSAMPLENR, 45 }, - { 926 * OVERSAMPLENR, 40 }, - { 946 * OVERSAMPLENR, 35 }, - { 962 * OVERSAMPLENR, 30 }, - { 977 * OVERSAMPLENR, 25 }, - { 987 * OVERSAMPLENR, 20 }, - { 995 * OVERSAMPLENR, 15 }, - { 1001 * OVERSAMPLENR, 10 }, - { 1010 * OVERSAMPLENR, 0 }, - { 1023 * OVERSAMPLENR, -40 } + { OV( 35), 180 }, // top rating 180C + { OV( 211), 140 }, + { OV( 233), 135 }, + { OV( 261), 130 }, + { OV( 290), 125 }, + { OV( 328), 120 }, + { OV( 362), 115 }, + { OV( 406), 110 }, + { OV( 446), 105 }, + { OV( 496), 100 }, + { OV( 539), 95 }, + { OV( 585), 90 }, + { OV( 629), 85 }, + { OV( 675), 80 }, + { OV( 718), 75 }, + { OV( 758), 70 }, + { OV( 793), 65 }, + { OV( 822), 60 }, + { OV( 841), 55 }, + { OV( 875), 50 }, + { OV( 899), 45 }, + { OV( 926), 40 }, + { OV( 946), 35 }, + { OV( 962), 30 }, + { OV( 977), 25 }, + { OV( 987), 20 }, + { OV( 995), 15 }, + { OV(1001), 10 }, + { OV(1010), 0 }, + { OV(1023), -40 } }; diff --git a/Marlin/thermistortable_13.h b/Marlin/thermistortable_13.h index 1269c35665..b4d827e455 100644 --- a/Marlin/thermistortable_13.h +++ b/Marlin/thermistortable_13.h @@ -22,27 +22,27 @@ // Hisens thermistor B25/50 =3950 +/-1% const short temptable_13[][2] PROGMEM = { - { 20.04 * OVERSAMPLENR, 300 }, - { 23.19 * OVERSAMPLENR, 290 }, - { 26.71 * OVERSAMPLENR, 280 }, - { 31.23 * OVERSAMPLENR, 270 }, - { 36.52 * OVERSAMPLENR, 260 }, - { 42.75 * OVERSAMPLENR, 250 }, - { 50.68 * OVERSAMPLENR, 240 }, - { 60.22 * OVERSAMPLENR, 230 }, - { 72.03 * OVERSAMPLENR, 220 }, - { 86.84 * OVERSAMPLENR, 210 }, - { 102.79 * OVERSAMPLENR, 200 }, - { 124.46 * OVERSAMPLENR, 190 }, - { 151.02 * OVERSAMPLENR, 180 }, - { 182.86 * OVERSAMPLENR, 170 }, - { 220.72 * OVERSAMPLENR, 160 }, - { 316.96 * OVERSAMPLENR, 140 }, - { 447.17 * OVERSAMPLENR, 120 }, - { 590.61 * OVERSAMPLENR, 100 }, - { 737.31 * OVERSAMPLENR, 80 }, - { 857.77 * OVERSAMPLENR, 60 }, - { 939.52 * OVERSAMPLENR, 40 }, - { 986.03 * OVERSAMPLENR, 20 }, - { 1008.7 * OVERSAMPLENR, 0 } + { OV( 20.04), 300 }, + { OV( 23.19), 290 }, + { OV( 26.71), 280 }, + { OV( 31.23), 270 }, + { OV( 36.52), 260 }, + { OV( 42.75), 250 }, + { OV( 50.68), 240 }, + { OV( 60.22), 230 }, + { OV( 72.03), 220 }, + { OV( 86.84), 210 }, + { OV(102.79), 200 }, + { OV(124.46), 190 }, + { OV(151.02), 180 }, + { OV(182.86), 170 }, + { OV(220.72), 160 }, + { OV(316.96), 140 }, + { OV(447.17), 120 }, + { OV(590.61), 100 }, + { OV(737.31), 80 }, + { OV(857.77), 60 }, + { OV(939.52), 40 }, + { OV(986.03), 20 }, + { OV(1008.7), 0 } }; diff --git a/Marlin/thermistortable_2.h b/Marlin/thermistortable_2.h index 1b56faed9d..03c2d39bea 100644 --- a/Marlin/thermistortable_2.h +++ b/Marlin/thermistortable_2.h @@ -26,36 +26,36 @@ // Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance // const short temptable_2[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 848 }, - { 30 * OVERSAMPLENR, 300 }, // top rating 300C - { 34 * OVERSAMPLENR, 290 }, - { 39 * OVERSAMPLENR, 280 }, - { 46 * OVERSAMPLENR, 270 }, - { 53 * OVERSAMPLENR, 260 }, - { 63 * OVERSAMPLENR, 250 }, - { 74 * OVERSAMPLENR, 240 }, - { 87 * OVERSAMPLENR, 230 }, - { 104 * OVERSAMPLENR, 220 }, - { 124 * OVERSAMPLENR, 210 }, - { 148 * OVERSAMPLENR, 200 }, - { 176 * OVERSAMPLENR, 190 }, - { 211 * OVERSAMPLENR, 180 }, - { 252 * OVERSAMPLENR, 170 }, - { 301 * OVERSAMPLENR, 160 }, - { 357 * OVERSAMPLENR, 150 }, - { 420 * OVERSAMPLENR, 140 }, - { 489 * OVERSAMPLENR, 130 }, - { 562 * OVERSAMPLENR, 120 }, - { 636 * OVERSAMPLENR, 110 }, - { 708 * OVERSAMPLENR, 100 }, - { 775 * OVERSAMPLENR, 90 }, - { 835 * OVERSAMPLENR, 80 }, - { 884 * OVERSAMPLENR, 70 }, - { 924 * OVERSAMPLENR, 60 }, - { 955 * OVERSAMPLENR, 50 }, - { 977 * OVERSAMPLENR, 40 }, - { 993 * OVERSAMPLENR, 30 }, - { 1004 * OVERSAMPLENR, 20 }, - { 1012 * OVERSAMPLENR, 10 }, - { 1016 * OVERSAMPLENR, 0 } + { OV( 1), 848 }, + { OV( 30), 300 }, // top rating 300C + { OV( 34), 290 }, + { OV( 39), 280 }, + { OV( 46), 270 }, + { OV( 53), 260 }, + { OV( 63), 250 }, + { OV( 74), 240 }, + { OV( 87), 230 }, + { OV( 104), 220 }, + { OV( 124), 210 }, + { OV( 148), 200 }, + { OV( 176), 190 }, + { OV( 211), 180 }, + { OV( 252), 170 }, + { OV( 301), 160 }, + { OV( 357), 150 }, + { OV( 420), 140 }, + { OV( 489), 130 }, + { OV( 562), 120 }, + { OV( 636), 110 }, + { OV( 708), 100 }, + { OV( 775), 90 }, + { OV( 835), 80 }, + { OV( 884), 70 }, + { OV( 924), 60 }, + { OV( 955), 50 }, + { OV( 977), 40 }, + { OV( 993), 30 }, + { OV(1004), 20 }, + { OV(1012), 10 }, + { OV(1016), 0 } }; diff --git a/Marlin/thermistortable_20.h b/Marlin/thermistortable_20.h index 1c27419591..5a01f78cf5 100644 --- a/Marlin/thermistortable_20.h +++ b/Marlin/thermistortable_20.h @@ -48,53 +48,53 @@ #define HEATER_BED_RAW_LO_TEMP 0 #endif const short temptable_20[][2] PROGMEM = { - { 0 * OVERSAMPLENR, 0 }, - { 227 * OVERSAMPLENR, 1 }, - { 236 * OVERSAMPLENR, 10 }, - { 245 * OVERSAMPLENR, 20 }, - { 253 * OVERSAMPLENR, 30 }, - { 262 * OVERSAMPLENR, 40 }, - { 270 * OVERSAMPLENR, 50 }, - { 279 * OVERSAMPLENR, 60 }, - { 287 * OVERSAMPLENR, 70 }, - { 295 * OVERSAMPLENR, 80 }, - { 304 * OVERSAMPLENR, 90 }, - { 312 * OVERSAMPLENR, 100 }, - { 320 * OVERSAMPLENR, 110 }, - { 329 * OVERSAMPLENR, 120 }, - { 337 * OVERSAMPLENR, 130 }, - { 345 * OVERSAMPLENR, 140 }, - { 353 * OVERSAMPLENR, 150 }, - { 361 * OVERSAMPLENR, 160 }, - { 369 * OVERSAMPLENR, 170 }, - { 377 * OVERSAMPLENR, 180 }, - { 385 * OVERSAMPLENR, 190 }, - { 393 * OVERSAMPLENR, 200 }, - { 401 * OVERSAMPLENR, 210 }, - { 409 * OVERSAMPLENR, 220 }, - { 417 * OVERSAMPLENR, 230 }, - { 424 * OVERSAMPLENR, 240 }, - { 432 * OVERSAMPLENR, 250 }, - { 440 * OVERSAMPLENR, 260 }, - { 447 * OVERSAMPLENR, 270 }, - { 455 * OVERSAMPLENR, 280 }, - { 463 * OVERSAMPLENR, 290 }, - { 470 * OVERSAMPLENR, 300 }, - { 478 * OVERSAMPLENR, 310 }, - { 485 * OVERSAMPLENR, 320 }, - { 493 * OVERSAMPLENR, 330 }, - { 500 * OVERSAMPLENR, 340 }, - { 507 * OVERSAMPLENR, 350 }, - { 515 * OVERSAMPLENR, 360 }, - { 522 * OVERSAMPLENR, 370 }, - { 529 * OVERSAMPLENR, 380 }, - { 537 * OVERSAMPLENR, 390 }, - { 544 * OVERSAMPLENR, 400 }, - { 614 * OVERSAMPLENR, 500 }, - { 681 * OVERSAMPLENR, 600 }, - { 744 * OVERSAMPLENR, 700 }, - { 805 * OVERSAMPLENR, 800 }, - { 862 * OVERSAMPLENR, 900 }, - { 917 * OVERSAMPLENR, 1000 }, - { 968 * OVERSAMPLENR, 1100 } + { OV( 0), 0 }, + { OV(227), 1 }, + { OV(236), 10 }, + { OV(245), 20 }, + { OV(253), 30 }, + { OV(262), 40 }, + { OV(270), 50 }, + { OV(279), 60 }, + { OV(287), 70 }, + { OV(295), 80 }, + { OV(304), 90 }, + { OV(312), 100 }, + { OV(320), 110 }, + { OV(329), 120 }, + { OV(337), 130 }, + { OV(345), 140 }, + { OV(353), 150 }, + { OV(361), 160 }, + { OV(369), 170 }, + { OV(377), 180 }, + { OV(385), 190 }, + { OV(393), 200 }, + { OV(401), 210 }, + { OV(409), 220 }, + { OV(417), 230 }, + { OV(424), 240 }, + { OV(432), 250 }, + { OV(440), 260 }, + { OV(447), 270 }, + { OV(455), 280 }, + { OV(463), 290 }, + { OV(470), 300 }, + { OV(478), 310 }, + { OV(485), 320 }, + { OV(493), 330 }, + { OV(500), 340 }, + { OV(507), 350 }, + { OV(515), 360 }, + { OV(522), 370 }, + { OV(529), 380 }, + { OV(537), 390 }, + { OV(544), 400 }, + { OV(614), 500 }, + { OV(681), 600 }, + { OV(744), 700 }, + { OV(805), 800 }, + { OV(862), 900 }, + { OV(917), 1000 }, + { OV(968), 1100 } }; diff --git a/Marlin/thermistortable_3.h b/Marlin/thermistortable_3.h index 0fc16d4bf7..3a5a0141f9 100644 --- a/Marlin/thermistortable_3.h +++ b/Marlin/thermistortable_3.h @@ -22,32 +22,32 @@ // mendel-parts const short temptable_3[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 864 }, - { 21 * OVERSAMPLENR, 300 }, - { 25 * OVERSAMPLENR, 290 }, - { 29 * OVERSAMPLENR, 280 }, - { 33 * OVERSAMPLENR, 270 }, - { 39 * OVERSAMPLENR, 260 }, - { 46 * OVERSAMPLENR, 250 }, - { 54 * OVERSAMPLENR, 240 }, - { 64 * OVERSAMPLENR, 230 }, - { 75 * OVERSAMPLENR, 220 }, - { 90 * OVERSAMPLENR, 210 }, - { 107 * OVERSAMPLENR, 200 }, - { 128 * OVERSAMPLENR, 190 }, - { 154 * OVERSAMPLENR, 180 }, - { 184 * OVERSAMPLENR, 170 }, - { 221 * OVERSAMPLENR, 160 }, - { 265 * OVERSAMPLENR, 150 }, - { 316 * OVERSAMPLENR, 140 }, - { 375 * OVERSAMPLENR, 130 }, - { 441 * OVERSAMPLENR, 120 }, - { 513 * OVERSAMPLENR, 110 }, - { 588 * OVERSAMPLENR, 100 }, - { 734 * OVERSAMPLENR, 80 }, - { 856 * OVERSAMPLENR, 60 }, - { 938 * OVERSAMPLENR, 40 }, - { 986 * OVERSAMPLENR, 20 }, - { 1008 * OVERSAMPLENR, 0 }, - { 1018 * OVERSAMPLENR, -20 } + { OV( 1), 864 }, + { OV( 21), 300 }, + { OV( 25), 290 }, + { OV( 29), 280 }, + { OV( 33), 270 }, + { OV( 39), 260 }, + { OV( 46), 250 }, + { OV( 54), 240 }, + { OV( 64), 230 }, + { OV( 75), 220 }, + { OV( 90), 210 }, + { OV( 107), 200 }, + { OV( 128), 190 }, + { OV( 154), 180 }, + { OV( 184), 170 }, + { OV( 221), 160 }, + { OV( 265), 150 }, + { OV( 316), 140 }, + { OV( 375), 130 }, + { OV( 441), 120 }, + { OV( 513), 110 }, + { OV( 588), 100 }, + { OV( 734), 80 }, + { OV( 856), 60 }, + { OV( 938), 40 }, + { OV( 986), 20 }, + { OV(1008), 0 }, + { OV(1018), -20 } }; diff --git a/Marlin/thermistortable_4.h b/Marlin/thermistortable_4.h index 83e60cd6ad..8a611a2064 100644 --- a/Marlin/thermistortable_4.h +++ b/Marlin/thermistortable_4.h @@ -22,24 +22,24 @@ // 10k thermistor const short temptable_4[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 430 }, - { 54 * OVERSAMPLENR, 137 }, - { 107 * OVERSAMPLENR, 107 }, - { 160 * OVERSAMPLENR, 91 }, - { 213 * OVERSAMPLENR, 80 }, - { 266 * OVERSAMPLENR, 71 }, - { 319 * OVERSAMPLENR, 64 }, - { 372 * OVERSAMPLENR, 57 }, - { 425 * OVERSAMPLENR, 51 }, - { 478 * OVERSAMPLENR, 46 }, - { 531 * OVERSAMPLENR, 41 }, - { 584 * OVERSAMPLENR, 35 }, - { 637 * OVERSAMPLENR, 30 }, - { 690 * OVERSAMPLENR, 25 }, - { 743 * OVERSAMPLENR, 20 }, - { 796 * OVERSAMPLENR, 14 }, - { 849 * OVERSAMPLENR, 7 }, - { 902 * OVERSAMPLENR, 0 }, - { 955 * OVERSAMPLENR, -11 }, - { 1008 * OVERSAMPLENR, -35 } + { OV( 1), 430 }, + { OV( 54), 137 }, + { OV( 107), 107 }, + { OV( 160), 91 }, + { OV( 213), 80 }, + { OV( 266), 71 }, + { OV( 319), 64 }, + { OV( 372), 57 }, + { OV( 425), 51 }, + { OV( 478), 46 }, + { OV( 531), 41 }, + { OV( 584), 35 }, + { OV( 637), 30 }, + { OV( 690), 25 }, + { OV( 743), 20 }, + { OV( 796), 14 }, + { OV( 849), 7 }, + { OV( 902), 0 }, + { OV( 955), -11 }, + { OV(1008), -35 } }; diff --git a/Marlin/thermistortable_5.h b/Marlin/thermistortable_5.h index 8bad71308f..07f68feb2b 100644 --- a/Marlin/thermistortable_5.h +++ b/Marlin/thermistortable_5.h @@ -25,36 +25,36 @@ // Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf // Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance const short temptable_5[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 713 }, - { 17 * OVERSAMPLENR, 300 }, // top rating 300C - { 20 * OVERSAMPLENR, 290 }, - { 23 * OVERSAMPLENR, 280 }, - { 27 * OVERSAMPLENR, 270 }, - { 31 * OVERSAMPLENR, 260 }, - { 37 * OVERSAMPLENR, 250 }, - { 43 * OVERSAMPLENR, 240 }, - { 51 * OVERSAMPLENR, 230 }, - { 61 * OVERSAMPLENR, 220 }, - { 73 * OVERSAMPLENR, 210 }, - { 87 * OVERSAMPLENR, 200 }, - { 106 * OVERSAMPLENR, 190 }, - { 128 * OVERSAMPLENR, 180 }, - { 155 * OVERSAMPLENR, 170 }, - { 189 * OVERSAMPLENR, 160 }, - { 230 * OVERSAMPLENR, 150 }, - { 278 * OVERSAMPLENR, 140 }, - { 336 * OVERSAMPLENR, 130 }, - { 402 * OVERSAMPLENR, 120 }, - { 476 * OVERSAMPLENR, 110 }, - { 554 * OVERSAMPLENR, 100 }, - { 635 * OVERSAMPLENR, 90 }, - { 713 * OVERSAMPLENR, 80 }, - { 784 * OVERSAMPLENR, 70 }, - { 846 * OVERSAMPLENR, 60 }, - { 897 * OVERSAMPLENR, 50 }, - { 937 * OVERSAMPLENR, 40 }, - { 966 * OVERSAMPLENR, 30 }, - { 986 * OVERSAMPLENR, 20 }, - { 1000 * OVERSAMPLENR, 10 }, - { 1010 * OVERSAMPLENR, 0 } + { OV( 1), 713 }, + { OV( 17), 300 }, // top rating 300C + { OV( 20), 290 }, + { OV( 23), 280 }, + { OV( 27), 270 }, + { OV( 31), 260 }, + { OV( 37), 250 }, + { OV( 43), 240 }, + { OV( 51), 230 }, + { OV( 61), 220 }, + { OV( 73), 210 }, + { OV( 87), 200 }, + { OV( 106), 190 }, + { OV( 128), 180 }, + { OV( 155), 170 }, + { OV( 189), 160 }, + { OV( 230), 150 }, + { OV( 278), 140 }, + { OV( 336), 130 }, + { OV( 402), 120 }, + { OV( 476), 110 }, + { OV( 554), 100 }, + { OV( 635), 90 }, + { OV( 713), 80 }, + { OV( 784), 70 }, + { OV( 846), 60 }, + { OV( 897), 50 }, + { OV( 937), 40 }, + { OV( 966), 30 }, + { OV( 986), 20 }, + { OV(1000), 10 }, + { OV(1010), 0 } }; diff --git a/Marlin/thermistortable_51.h b/Marlin/thermistortable_51.h index 44f7142bbe..198f564c4f 100644 --- a/Marlin/thermistortable_51.h +++ b/Marlin/thermistortable_51.h @@ -25,57 +25,57 @@ // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: Twice the resolution and better linearity from 150C to 200C const short temptable_51[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 350 }, - { 190 * OVERSAMPLENR, 250 }, // top rating 250C - { 203 * OVERSAMPLENR, 245 }, - { 217 * OVERSAMPLENR, 240 }, - { 232 * OVERSAMPLENR, 235 }, - { 248 * OVERSAMPLENR, 230 }, - { 265 * OVERSAMPLENR, 225 }, - { 283 * OVERSAMPLENR, 220 }, - { 302 * OVERSAMPLENR, 215 }, - { 322 * OVERSAMPLENR, 210 }, - { 344 * OVERSAMPLENR, 205 }, - { 366 * OVERSAMPLENR, 200 }, - { 390 * OVERSAMPLENR, 195 }, - { 415 * OVERSAMPLENR, 190 }, - { 440 * OVERSAMPLENR, 185 }, - { 467 * OVERSAMPLENR, 180 }, - { 494 * OVERSAMPLENR, 175 }, - { 522 * OVERSAMPLENR, 170 }, - { 551 * OVERSAMPLENR, 165 }, - { 580 * OVERSAMPLENR, 160 }, - { 609 * OVERSAMPLENR, 155 }, - { 638 * OVERSAMPLENR, 150 }, - { 666 * OVERSAMPLENR, 145 }, - { 695 * OVERSAMPLENR, 140 }, - { 722 * OVERSAMPLENR, 135 }, - { 749 * OVERSAMPLENR, 130 }, - { 775 * OVERSAMPLENR, 125 }, - { 800 * OVERSAMPLENR, 120 }, - { 823 * OVERSAMPLENR, 115 }, - { 845 * OVERSAMPLENR, 110 }, - { 865 * OVERSAMPLENR, 105 }, - { 884 * OVERSAMPLENR, 100 }, - { 901 * OVERSAMPLENR, 95 }, - { 917 * OVERSAMPLENR, 90 }, - { 932 * OVERSAMPLENR, 85 }, - { 944 * OVERSAMPLENR, 80 }, - { 956 * OVERSAMPLENR, 75 }, - { 966 * OVERSAMPLENR, 70 }, - { 975 * OVERSAMPLENR, 65 }, - { 982 * OVERSAMPLENR, 60 }, - { 989 * OVERSAMPLENR, 55 }, - { 995 * OVERSAMPLENR, 50 }, - { 1000 * OVERSAMPLENR, 45 }, - { 1004 * OVERSAMPLENR, 40 }, - { 1007 * OVERSAMPLENR, 35 }, - { 1010 * OVERSAMPLENR, 30 }, - { 1013 * OVERSAMPLENR, 25 }, - { 1015 * OVERSAMPLENR, 20 }, - { 1017 * OVERSAMPLENR, 15 }, - { 1018 * OVERSAMPLENR, 10 }, - { 1019 * OVERSAMPLENR, 5 }, - { 1020 * OVERSAMPLENR, 0 }, - { 1021 * OVERSAMPLENR, -5 } + { OV( 1), 350 }, + { OV( 190), 250 }, // top rating 250C + { OV( 203), 245 }, + { OV( 217), 240 }, + { OV( 232), 235 }, + { OV( 248), 230 }, + { OV( 265), 225 }, + { OV( 283), 220 }, + { OV( 302), 215 }, + { OV( 322), 210 }, + { OV( 344), 205 }, + { OV( 366), 200 }, + { OV( 390), 195 }, + { OV( 415), 190 }, + { OV( 440), 185 }, + { OV( 467), 180 }, + { OV( 494), 175 }, + { OV( 522), 170 }, + { OV( 551), 165 }, + { OV( 580), 160 }, + { OV( 609), 155 }, + { OV( 638), 150 }, + { OV( 666), 145 }, + { OV( 695), 140 }, + { OV( 722), 135 }, + { OV( 749), 130 }, + { OV( 775), 125 }, + { OV( 800), 120 }, + { OV( 823), 115 }, + { OV( 845), 110 }, + { OV( 865), 105 }, + { OV( 884), 100 }, + { OV( 901), 95 }, + { OV( 917), 90 }, + { OV( 932), 85 }, + { OV( 944), 80 }, + { OV( 956), 75 }, + { OV( 966), 70 }, + { OV( 975), 65 }, + { OV( 982), 60 }, + { OV( 989), 55 }, + { OV( 995), 50 }, + { OV(1000), 45 }, + { OV(1004), 40 }, + { OV(1007), 35 }, + { OV(1010), 30 }, + { OV(1013), 25 }, + { OV(1015), 20 }, + { OV(1017), 15 }, + { OV(1018), 10 }, + { OV(1019), 5 }, + { OV(1020), 0 }, + { OV(1021), -5 } }; diff --git a/Marlin/thermistortable_52.h b/Marlin/thermistortable_52.h index bf4e6a9e8b..361ebb4276 100644 --- a/Marlin/thermistortable_52.h +++ b/Marlin/thermistortable_52.h @@ -25,36 +25,36 @@ // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: More resolution and better linearity from 150C to 200C const short temptable_52[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 500 }, - { 125 * OVERSAMPLENR, 300 }, // top rating 300C - { 142 * OVERSAMPLENR, 290 }, - { 162 * OVERSAMPLENR, 280 }, - { 185 * OVERSAMPLENR, 270 }, - { 211 * OVERSAMPLENR, 260 }, - { 240 * OVERSAMPLENR, 250 }, - { 274 * OVERSAMPLENR, 240 }, - { 312 * OVERSAMPLENR, 230 }, - { 355 * OVERSAMPLENR, 220 }, - { 401 * OVERSAMPLENR, 210 }, - { 452 * OVERSAMPLENR, 200 }, - { 506 * OVERSAMPLENR, 190 }, - { 563 * OVERSAMPLENR, 180 }, - { 620 * OVERSAMPLENR, 170 }, - { 677 * OVERSAMPLENR, 160 }, - { 732 * OVERSAMPLENR, 150 }, - { 783 * OVERSAMPLENR, 140 }, - { 830 * OVERSAMPLENR, 130 }, - { 871 * OVERSAMPLENR, 120 }, - { 906 * OVERSAMPLENR, 110 }, - { 935 * OVERSAMPLENR, 100 }, - { 958 * OVERSAMPLENR, 90 }, - { 976 * OVERSAMPLENR, 80 }, - { 990 * OVERSAMPLENR, 70 }, - { 1000 * OVERSAMPLENR, 60 }, - { 1008 * OVERSAMPLENR, 50 }, - { 1013 * OVERSAMPLENR, 40 }, - { 1017 * OVERSAMPLENR, 30 }, - { 1019 * OVERSAMPLENR, 20 }, - { 1021 * OVERSAMPLENR, 10 }, - { 1022 * OVERSAMPLENR, 0 } + { OV( 1), 500 }, + { OV( 125), 300 }, // top rating 300C + { OV( 142), 290 }, + { OV( 162), 280 }, + { OV( 185), 270 }, + { OV( 211), 260 }, + { OV( 240), 250 }, + { OV( 274), 240 }, + { OV( 312), 230 }, + { OV( 355), 220 }, + { OV( 401), 210 }, + { OV( 452), 200 }, + { OV( 506), 190 }, + { OV( 563), 180 }, + { OV( 620), 170 }, + { OV( 677), 160 }, + { OV( 732), 150 }, + { OV( 783), 140 }, + { OV( 830), 130 }, + { OV( 871), 120 }, + { OV( 906), 110 }, + { OV( 935), 100 }, + { OV( 958), 90 }, + { OV( 976), 80 }, + { OV( 990), 70 }, + { OV(1000), 60 }, + { OV(1008), 50 }, + { OV(1013), 40 }, + { OV(1017), 30 }, + { OV(1019), 20 }, + { OV(1021), 10 }, + { OV(1022), 0 } }; diff --git a/Marlin/thermistortable_55.h b/Marlin/thermistortable_55.h index 76e43db6ee..c4f3961dd4 100644 --- a/Marlin/thermistortable_55.h +++ b/Marlin/thermistortable_55.h @@ -25,36 +25,36 @@ // Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance // Advantage: More resolution and better linearity from 150C to 200C const short temptable_55[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 500 }, - { 76 * OVERSAMPLENR, 300 }, - { 87 * OVERSAMPLENR, 290 }, - { 100 * OVERSAMPLENR, 280 }, - { 114 * OVERSAMPLENR, 270 }, - { 131 * OVERSAMPLENR, 260 }, - { 152 * OVERSAMPLENR, 250 }, - { 175 * OVERSAMPLENR, 240 }, - { 202 * OVERSAMPLENR, 230 }, - { 234 * OVERSAMPLENR, 220 }, - { 271 * OVERSAMPLENR, 210 }, - { 312 * OVERSAMPLENR, 200 }, - { 359 * OVERSAMPLENR, 190 }, - { 411 * OVERSAMPLENR, 180 }, - { 467 * OVERSAMPLENR, 170 }, - { 527 * OVERSAMPLENR, 160 }, - { 590 * OVERSAMPLENR, 150 }, - { 652 * OVERSAMPLENR, 140 }, - { 713 * OVERSAMPLENR, 130 }, - { 770 * OVERSAMPLENR, 120 }, - { 822 * OVERSAMPLENR, 110 }, - { 867 * OVERSAMPLENR, 100 }, - { 905 * OVERSAMPLENR, 90 }, - { 936 * OVERSAMPLENR, 80 }, - { 961 * OVERSAMPLENR, 70 }, - { 979 * OVERSAMPLENR, 60 }, - { 993 * OVERSAMPLENR, 50 }, - { 1003 * OVERSAMPLENR, 40 }, - { 1010 * OVERSAMPLENR, 30 }, - { 1015 * OVERSAMPLENR, 20 }, - { 1018 * OVERSAMPLENR, 10 }, - { 1020 * OVERSAMPLENR, 0 } + { OV( 1), 500 }, + { OV( 76), 300 }, + { OV( 87), 290 }, + { OV( 100), 280 }, + { OV( 114), 270 }, + { OV( 131), 260 }, + { OV( 152), 250 }, + { OV( 175), 240 }, + { OV( 202), 230 }, + { OV( 234), 220 }, + { OV( 271), 210 }, + { OV( 312), 200 }, + { OV( 359), 190 }, + { OV( 411), 180 }, + { OV( 467), 170 }, + { OV( 527), 160 }, + { OV( 590), 150 }, + { OV( 652), 140 }, + { OV( 713), 130 }, + { OV( 770), 120 }, + { OV( 822), 110 }, + { OV( 867), 100 }, + { OV( 905), 90 }, + { OV( 936), 80 }, + { OV( 961), 70 }, + { OV( 979), 60 }, + { OV( 993), 50 }, + { OV(1003), 40 }, + { OV(1010), 30 }, + { OV(1015), 20 }, + { OV(1018), 10 }, + { OV(1020), 0 } }; diff --git a/Marlin/thermistortable_6.h b/Marlin/thermistortable_6.h index d270b60d37..ab21ae6677 100644 --- a/Marlin/thermistortable_6.h +++ b/Marlin/thermistortable_6.h @@ -22,42 +22,42 @@ // 100k Epcos thermistor const short temptable_6[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 350 }, - { 28 * OVERSAMPLENR, 250 }, // top rating 250C - { 31 * OVERSAMPLENR, 245 }, - { 35 * OVERSAMPLENR, 240 }, - { 39 * OVERSAMPLENR, 235 }, - { 42 * OVERSAMPLENR, 230 }, - { 44 * OVERSAMPLENR, 225 }, - { 49 * OVERSAMPLENR, 220 }, - { 53 * OVERSAMPLENR, 215 }, - { 62 * OVERSAMPLENR, 210 }, - { 71 * OVERSAMPLENR, 205 }, // fitted graphically - { 78 * OVERSAMPLENR, 200 }, // fitted graphically - { 94 * OVERSAMPLENR, 190 }, - { 102 * OVERSAMPLENR, 185 }, - { 116 * OVERSAMPLENR, 170 }, - { 143 * OVERSAMPLENR, 160 }, - { 183 * OVERSAMPLENR, 150 }, - { 223 * OVERSAMPLENR, 140 }, - { 270 * OVERSAMPLENR, 130 }, - { 318 * OVERSAMPLENR, 120 }, - { 383 * OVERSAMPLENR, 110 }, - { 413 * OVERSAMPLENR, 105 }, - { 439 * OVERSAMPLENR, 100 }, - { 484 * OVERSAMPLENR, 95 }, - { 513 * OVERSAMPLENR, 90 }, - { 607 * OVERSAMPLENR, 80 }, - { 664 * OVERSAMPLENR, 70 }, - { 781 * OVERSAMPLENR, 60 }, - { 810 * OVERSAMPLENR, 55 }, - { 849 * OVERSAMPLENR, 50 }, - { 914 * OVERSAMPLENR, 45 }, - { 914 * OVERSAMPLENR, 40 }, - { 935 * OVERSAMPLENR, 35 }, - { 954 * OVERSAMPLENR, 30 }, - { 970 * OVERSAMPLENR, 25 }, - { 978 * OVERSAMPLENR, 22 }, - { 1008 * OVERSAMPLENR, 3 }, - { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C + { OV( 1), 350 }, + { OV( 28), 250 }, // top rating 250C + { OV( 31), 245 }, + { OV( 35), 240 }, + { OV( 39), 235 }, + { OV( 42), 230 }, + { OV( 44), 225 }, + { OV( 49), 220 }, + { OV( 53), 215 }, + { OV( 62), 210 }, + { OV( 71), 205 }, // fitted graphically + { OV( 78), 200 }, // fitted graphically + { OV( 94), 190 }, + { OV( 102), 185 }, + { OV( 116), 170 }, + { OV( 143), 160 }, + { OV( 183), 150 }, + { OV( 223), 140 }, + { OV( 270), 130 }, + { OV( 318), 120 }, + { OV( 383), 110 }, + { OV( 413), 105 }, + { OV( 439), 100 }, + { OV( 484), 95 }, + { OV( 513), 90 }, + { OV( 607), 80 }, + { OV( 664), 70 }, + { OV( 781), 60 }, + { OV( 810), 55 }, + { OV( 849), 50 }, + { OV( 914), 45 }, + { OV( 914), 40 }, + { OV( 935), 35 }, + { OV( 954), 30 }, + { OV( 970), 25 }, + { OV( 978), 22 }, + { OV(1008), 3 }, + { OV(1023), 0 } // to allow internal 0 degrees C }; diff --git a/Marlin/thermistortable_60.h b/Marlin/thermistortable_60.h index a1c2645b9e..3340ac6b56 100644 --- a/Marlin/thermistortable_60.h +++ b/Marlin/thermistortable_60.h @@ -30,76 +30,76 @@ // min adc: 1 at 0.0048828125 V // max adc: 1023 at 4.9951171875 V const short temptable_60[][2] PROGMEM = { - { 51 * OVERSAMPLENR, 272 }, - { 61 * OVERSAMPLENR, 258 }, - { 71 * OVERSAMPLENR, 247 }, - { 81 * OVERSAMPLENR, 237 }, - { 91 * OVERSAMPLENR, 229 }, - { 101 * OVERSAMPLENR, 221 }, - { 131 * OVERSAMPLENR, 204 }, - { 161 * OVERSAMPLENR, 190 }, - { 191 * OVERSAMPLENR, 179 }, - { 231 * OVERSAMPLENR, 167 }, - { 271 * OVERSAMPLENR, 157 }, - { 311 * OVERSAMPLENR, 148 }, - { 351 * OVERSAMPLENR, 140 }, - { 381 * OVERSAMPLENR, 135 }, - { 411 * OVERSAMPLENR, 130 }, - { 441 * OVERSAMPLENR, 125 }, - { 451 * OVERSAMPLENR, 123 }, - { 461 * OVERSAMPLENR, 122 }, - { 471 * OVERSAMPLENR, 120 }, - { 481 * OVERSAMPLENR, 119 }, - { 491 * OVERSAMPLENR, 117 }, - { 501 * OVERSAMPLENR, 116 }, - { 511 * OVERSAMPLENR, 114 }, - { 521 * OVERSAMPLENR, 113 }, - { 531 * OVERSAMPLENR, 111 }, - { 541 * OVERSAMPLENR, 110 }, - { 551 * OVERSAMPLENR, 108 }, - { 561 * OVERSAMPLENR, 107 }, - { 571 * OVERSAMPLENR, 105 }, - { 581 * OVERSAMPLENR, 104 }, - { 591 * OVERSAMPLENR, 102 }, - { 601 * OVERSAMPLENR, 101 }, - { 611 * OVERSAMPLENR, 100 }, - { 621 * OVERSAMPLENR, 98 }, - { 631 * OVERSAMPLENR, 97 }, - { 641 * OVERSAMPLENR, 95 }, - { 651 * OVERSAMPLENR, 94 }, - { 661 * OVERSAMPLENR, 92 }, - { 671 * OVERSAMPLENR, 91 }, - { 681 * OVERSAMPLENR, 90 }, - { 691 * OVERSAMPLENR, 88 }, - { 701 * OVERSAMPLENR, 87 }, - { 711 * OVERSAMPLENR, 85 }, - { 721 * OVERSAMPLENR, 84 }, - { 731 * OVERSAMPLENR, 82 }, - { 741 * OVERSAMPLENR, 81 }, - { 751 * OVERSAMPLENR, 79 }, - { 761 * OVERSAMPLENR, 77 }, - { 771 * OVERSAMPLENR, 76 }, - { 781 * OVERSAMPLENR, 74 }, - { 791 * OVERSAMPLENR, 72 }, - { 801 * OVERSAMPLENR, 71 }, - { 811 * OVERSAMPLENR, 69 }, - { 821 * OVERSAMPLENR, 67 }, - { 831 * OVERSAMPLENR, 65 }, - { 841 * OVERSAMPLENR, 63 }, - { 851 * OVERSAMPLENR, 62 }, - { 861 * OVERSAMPLENR, 60 }, - { 871 * OVERSAMPLENR, 57 }, - { 881 * OVERSAMPLENR, 55 }, - { 891 * OVERSAMPLENR, 53 }, - { 901 * OVERSAMPLENR, 51 }, - { 911 * OVERSAMPLENR, 48 }, - { 921 * OVERSAMPLENR, 45 }, - { 931 * OVERSAMPLENR, 42 }, - { 941 * OVERSAMPLENR, 39 }, - { 951 * OVERSAMPLENR, 36 }, - { 961 * OVERSAMPLENR, 32 }, - { 981 * OVERSAMPLENR, 23 }, - { 991 * OVERSAMPLENR, 17 }, - { 1001 * OVERSAMPLENR, 9 }, - { 1008 * OVERSAMPLENR, 0 } + { OV( 51), 272 }, + { OV( 61), 258 }, + { OV( 71), 247 }, + { OV( 81), 237 }, + { OV( 91), 229 }, + { OV( 101), 221 }, + { OV( 131), 204 }, + { OV( 161), 190 }, + { OV( 191), 179 }, + { OV( 231), 167 }, + { OV( 271), 157 }, + { OV( 311), 148 }, + { OV( 351), 140 }, + { OV( 381), 135 }, + { OV( 411), 130 }, + { OV( 441), 125 }, + { OV( 451), 123 }, + { OV( 461), 122 }, + { OV( 471), 120 }, + { OV( 481), 119 }, + { OV( 491), 117 }, + { OV( 501), 116 }, + { OV( 511), 114 }, + { OV( 521), 113 }, + { OV( 531), 111 }, + { OV( 541), 110 }, + { OV( 551), 108 }, + { OV( 561), 107 }, + { OV( 571), 105 }, + { OV( 581), 104 }, + { OV( 591), 102 }, + { OV( 601), 101 }, + { OV( 611), 100 }, + { OV( 621), 98 }, + { OV( 631), 97 }, + { OV( 641), 95 }, + { OV( 651), 94 }, + { OV( 661), 92 }, + { OV( 671), 91 }, + { OV( 681), 90 }, + { OV( 691), 88 }, + { OV( 701), 87 }, + { OV( 711), 85 }, + { OV( 721), 84 }, + { OV( 731), 82 }, + { OV( 741), 81 }, + { OV( 751), 79 }, + { OV( 761), 77 }, + { OV( 771), 76 }, + { OV( 781), 74 }, + { OV( 791), 72 }, + { OV( 801), 71 }, + { OV( 811), 69 }, + { OV( 821), 67 }, + { OV( 831), 65 }, + { OV( 841), 63 }, + { OV( 851), 62 }, + { OV( 861), 60 }, + { OV( 871), 57 }, + { OV( 881), 55 }, + { OV( 891), 53 }, + { OV( 901), 51 }, + { OV( 911), 48 }, + { OV( 921), 45 }, + { OV( 931), 42 }, + { OV( 941), 39 }, + { OV( 951), 36 }, + { OV( 961), 32 }, + { OV( 981), 23 }, + { OV( 991), 17 }, + { OV(1001), 9 }, + { OV(1008), 0 } }; diff --git a/Marlin/thermistortable_66.h b/Marlin/thermistortable_66.h index b23961d10f..78d5fb8bfa 100644 --- a/Marlin/thermistortable_66.h +++ b/Marlin/thermistortable_66.h @@ -22,31 +22,31 @@ // DyzeDesign 500°C Thermistor const short temptable_66[][2] PROGMEM = { - { 17.5 * OVERSAMPLENR, 850 }, - { 17.9 * OVERSAMPLENR, 500 }, - { 21.7 * OVERSAMPLENR, 480 }, - { 26.6 * OVERSAMPLENR, 460 }, - { 33.1 * OVERSAMPLENR, 440 }, - { 41.0 * OVERSAMPLENR, 420 }, - { 52.3 * OVERSAMPLENR, 400 }, - { 67.7 * OVERSAMPLENR, 380 }, - { 86.5 * OVERSAMPLENR, 360 }, - { 112.0 * OVERSAMPLENR, 340 }, - { 147.2 * OVERSAMPLENR, 320 }, - { 194.0 * OVERSAMPLENR, 300 }, - { 254.3 * OVERSAMPLENR, 280 }, - { 330.2 * OVERSAMPLENR, 260 }, - { 427.9 * OVERSAMPLENR, 240 }, - { 533.4 * OVERSAMPLENR, 220 }, - { 646.5 * OVERSAMPLENR, 200 }, - { 754.4 * OVERSAMPLENR, 180 }, - { 844.3 * OVERSAMPLENR, 160 }, - { 911.7 * OVERSAMPLENR, 140 }, - { 958.6 * OVERSAMPLENR, 120 }, - { 988.8 * OVERSAMPLENR, 100 }, - { 1006.6 * OVERSAMPLENR, 80 }, - { 1015.8 * OVERSAMPLENR, 60 }, - { 1021.3 * OVERSAMPLENR, 30 }, - { 1023 * OVERSAMPLENR - 1, 25}, - { 1023 * OVERSAMPLENR, 20} + { OV( 17.5), 850 }, + { OV( 17.9), 500 }, + { OV( 21.7), 480 }, + { OV( 26.6), 460 }, + { OV( 33.1), 440 }, + { OV( 41.0), 420 }, + { OV( 52.3), 400 }, + { OV( 67.7), 380 }, + { OV( 86.5), 360 }, + { OV( 112.0), 340 }, + { OV( 147.2), 320 }, + { OV( 194.0), 300 }, + { OV( 254.3), 280 }, + { OV( 330.2), 260 }, + { OV( 427.9), 240 }, + { OV( 533.4), 220 }, + { OV( 646.5), 200 }, + { OV( 754.4), 180 }, + { OV( 844.3), 160 }, + { OV( 911.7), 140 }, + { OV( 958.6), 120 }, + { OV( 988.8), 100 }, + { OV(1006.6), 80 }, + { OV(1015.8), 60 }, + { OV(1021.3), 30 }, + { OV(1023) - 1, 25}, + { OV( 1023), 20} }; diff --git a/Marlin/thermistortable_7.h b/Marlin/thermistortable_7.h index 3b4f63b7a6..5302a40568 100644 --- a/Marlin/thermistortable_7.h +++ b/Marlin/thermistortable_7.h @@ -22,62 +22,62 @@ // 100k Honeywell 135-104LAG-J01 const short temptable_7[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 941 }, - { 19 * OVERSAMPLENR, 362 }, - { 37 * OVERSAMPLENR, 299 }, // top rating 300C - { 55 * OVERSAMPLENR, 266 }, - { 73 * OVERSAMPLENR, 245 }, - { 91 * OVERSAMPLENR, 229 }, - { 109 * OVERSAMPLENR, 216 }, - { 127 * OVERSAMPLENR, 206 }, - { 145 * OVERSAMPLENR, 197 }, - { 163 * OVERSAMPLENR, 190 }, - { 181 * OVERSAMPLENR, 183 }, - { 199 * OVERSAMPLENR, 177 }, - { 217 * OVERSAMPLENR, 171 }, - { 235 * OVERSAMPLENR, 166 }, - { 253 * OVERSAMPLENR, 162 }, - { 271 * OVERSAMPLENR, 157 }, - { 289 * OVERSAMPLENR, 153 }, - { 307 * OVERSAMPLENR, 149 }, - { 325 * OVERSAMPLENR, 146 }, - { 343 * OVERSAMPLENR, 142 }, - { 361 * OVERSAMPLENR, 139 }, - { 379 * OVERSAMPLENR, 135 }, - { 397 * OVERSAMPLENR, 132 }, - { 415 * OVERSAMPLENR, 129 }, - { 433 * OVERSAMPLENR, 126 }, - { 451 * OVERSAMPLENR, 123 }, - { 469 * OVERSAMPLENR, 121 }, - { 487 * OVERSAMPLENR, 118 }, - { 505 * OVERSAMPLENR, 115 }, - { 523 * OVERSAMPLENR, 112 }, - { 541 * OVERSAMPLENR, 110 }, - { 559 * OVERSAMPLENR, 107 }, - { 577 * OVERSAMPLENR, 105 }, - { 595 * OVERSAMPLENR, 102 }, - { 613 * OVERSAMPLENR, 99 }, - { 631 * OVERSAMPLENR, 97 }, - { 649 * OVERSAMPLENR, 94 }, - { 667 * OVERSAMPLENR, 92 }, - { 685 * OVERSAMPLENR, 89 }, - { 703 * OVERSAMPLENR, 86 }, - { 721 * OVERSAMPLENR, 84 }, - { 739 * OVERSAMPLENR, 81 }, - { 757 * OVERSAMPLENR, 78 }, - { 775 * OVERSAMPLENR, 75 }, - { 793 * OVERSAMPLENR, 72 }, - { 811 * OVERSAMPLENR, 69 }, - { 829 * OVERSAMPLENR, 66 }, - { 847 * OVERSAMPLENR, 62 }, - { 865 * OVERSAMPLENR, 59 }, - { 883 * OVERSAMPLENR, 55 }, - { 901 * OVERSAMPLENR, 51 }, - { 919 * OVERSAMPLENR, 46 }, - { 937 * OVERSAMPLENR, 41 }, - { 955 * OVERSAMPLENR, 35 }, - { 973 * OVERSAMPLENR, 27 }, - { 991 * OVERSAMPLENR, 17 }, - { 1009 * OVERSAMPLENR, 1 }, - { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C + { OV( 1), 941 }, + { OV( 19), 362 }, + { OV( 37), 299 }, // top rating 300C + { OV( 55), 266 }, + { OV( 73), 245 }, + { OV( 91), 229 }, + { OV( 109), 216 }, + { OV( 127), 206 }, + { OV( 145), 197 }, + { OV( 163), 190 }, + { OV( 181), 183 }, + { OV( 199), 177 }, + { OV( 217), 171 }, + { OV( 235), 166 }, + { OV( 253), 162 }, + { OV( 271), 157 }, + { OV( 289), 153 }, + { OV( 307), 149 }, + { OV( 325), 146 }, + { OV( 343), 142 }, + { OV( 361), 139 }, + { OV( 379), 135 }, + { OV( 397), 132 }, + { OV( 415), 129 }, + { OV( 433), 126 }, + { OV( 451), 123 }, + { OV( 469), 121 }, + { OV( 487), 118 }, + { OV( 505), 115 }, + { OV( 523), 112 }, + { OV( 541), 110 }, + { OV( 559), 107 }, + { OV( 577), 105 }, + { OV( 595), 102 }, + { OV( 613), 99 }, + { OV( 631), 97 }, + { OV( 649), 94 }, + { OV( 667), 92 }, + { OV( 685), 89 }, + { OV( 703), 86 }, + { OV( 721), 84 }, + { OV( 739), 81 }, + { OV( 757), 78 }, + { OV( 775), 75 }, + { OV( 793), 72 }, + { OV( 811), 69 }, + { OV( 829), 66 }, + { OV( 847), 62 }, + { OV( 865), 59 }, + { OV( 883), 55 }, + { OV( 901), 51 }, + { OV( 919), 46 }, + { OV( 937), 41 }, + { OV( 955), 35 }, + { OV( 973), 27 }, + { OV( 991), 17 }, + { OV(1009), 1 }, + { OV(1023), 0 } // to allow internal 0 degrees C }; diff --git a/Marlin/thermistortable_70.h b/Marlin/thermistortable_70.h index 70440590da..990e45f3c0 100644 --- a/Marlin/thermistortable_70.h +++ b/Marlin/thermistortable_70.h @@ -22,65 +22,65 @@ // bqh2 stock thermistor const short temptable_70[][2] PROGMEM = { - { 22 * OVERSAMPLENR, 300 }, - { 24 * OVERSAMPLENR, 295 }, - { 25 * OVERSAMPLENR, 290 }, - { 27 * OVERSAMPLENR, 285 }, - { 29 * OVERSAMPLENR, 280 }, - { 32 * OVERSAMPLENR, 275 }, - { 34 * OVERSAMPLENR, 270 }, - { 37 * OVERSAMPLENR, 265 }, - { 40 * OVERSAMPLENR, 260 }, - { 43 * OVERSAMPLENR, 255 }, - { 46 * OVERSAMPLENR, 250 }, - { 50 * OVERSAMPLENR, 245 }, - { 54 * OVERSAMPLENR, 240 }, - { 59 * OVERSAMPLENR, 235 }, - { 64 * OVERSAMPLENR, 230 }, - { 70 * OVERSAMPLENR, 225 }, - { 76 * OVERSAMPLENR, 220 }, - { 83 * OVERSAMPLENR, 215 }, - { 90 * OVERSAMPLENR, 210 }, - { 99 * OVERSAMPLENR, 205 }, - { 108 * OVERSAMPLENR, 200 }, - { 118 * OVERSAMPLENR, 195 }, - { 129 * OVERSAMPLENR, 190 }, - { 141 * OVERSAMPLENR, 185 }, - { 154 * OVERSAMPLENR, 180 }, - { 169 * OVERSAMPLENR, 175 }, - { 185 * OVERSAMPLENR, 170 }, - { 203 * OVERSAMPLENR, 165 }, - { 222 * OVERSAMPLENR, 160 }, - { 243 * OVERSAMPLENR, 155 }, - { 266 * OVERSAMPLENR, 150 }, - { 290 * OVERSAMPLENR, 145 }, - { 317 * OVERSAMPLENR, 140 }, - { 346 * OVERSAMPLENR, 135 }, - { 376 * OVERSAMPLENR, 130 }, - { 408 * OVERSAMPLENR, 125 }, - { 442 * OVERSAMPLENR, 120 }, - { 477 * OVERSAMPLENR, 115 }, - { 513 * OVERSAMPLENR, 110 }, - { 551 * OVERSAMPLENR, 105 }, - { 588 * OVERSAMPLENR, 100 }, - { 626 * OVERSAMPLENR, 95 }, - { 663 * OVERSAMPLENR, 90 }, - { 699 * OVERSAMPLENR, 85 }, - { 735 * OVERSAMPLENR, 80 }, - { 768 * OVERSAMPLENR, 75 }, - { 800 * OVERSAMPLENR, 70 }, - { 829 * OVERSAMPLENR, 65 }, - { 856 * OVERSAMPLENR, 60 }, - { 881 * OVERSAMPLENR, 55 }, - { 903 * OVERSAMPLENR, 50 }, - { 922 * OVERSAMPLENR, 45 }, - { 939 * OVERSAMPLENR, 40 }, - { 954 * OVERSAMPLENR, 35 }, - { 966 * OVERSAMPLENR, 30 }, - { 977 * OVERSAMPLENR, 25 }, - { 986 * OVERSAMPLENR, 20 }, - { 994 * OVERSAMPLENR, 15 }, - { 1000 * OVERSAMPLENR, 10 }, - { 1005 * OVERSAMPLENR, 5 }, - { 1009 * OVERSAMPLENR, 0 } // safety + { OV( 22), 300 }, + { OV( 24), 295 }, + { OV( 25), 290 }, + { OV( 27), 285 }, + { OV( 29), 280 }, + { OV( 32), 275 }, + { OV( 34), 270 }, + { OV( 37), 265 }, + { OV( 40), 260 }, + { OV( 43), 255 }, + { OV( 46), 250 }, + { OV( 50), 245 }, + { OV( 54), 240 }, + { OV( 59), 235 }, + { OV( 64), 230 }, + { OV( 70), 225 }, + { OV( 76), 220 }, + { OV( 83), 215 }, + { OV( 90), 210 }, + { OV( 99), 205 }, + { OV( 108), 200 }, + { OV( 118), 195 }, + { OV( 129), 190 }, + { OV( 141), 185 }, + { OV( 154), 180 }, + { OV( 169), 175 }, + { OV( 185), 170 }, + { OV( 203), 165 }, + { OV( 222), 160 }, + { OV( 243), 155 }, + { OV( 266), 150 }, + { OV( 290), 145 }, + { OV( 317), 140 }, + { OV( 346), 135 }, + { OV( 376), 130 }, + { OV( 408), 125 }, + { OV( 442), 120 }, + { OV( 477), 115 }, + { OV( 513), 110 }, + { OV( 551), 105 }, + { OV( 588), 100 }, + { OV( 626), 95 }, + { OV( 663), 90 }, + { OV( 699), 85 }, + { OV( 735), 80 }, + { OV( 768), 75 }, + { OV( 800), 70 }, + { OV( 829), 65 }, + { OV( 856), 60 }, + { OV( 881), 55 }, + { OV( 903), 50 }, + { OV( 922), 45 }, + { OV( 939), 40 }, + { OV( 954), 35 }, + { OV( 966), 30 }, + { OV( 977), 25 }, + { OV( 986), 20 }, + { OV( 994), 15 }, + { OV(1000), 10 }, + { OV(1005), 5 }, + { OV(1009), 0 } // safety }; diff --git a/Marlin/thermistortable_71.h b/Marlin/thermistortable_71.h index 9d90e87bb4..2ba14d0cbe 100644 --- a/Marlin/thermistortable_71.h +++ b/Marlin/thermistortable_71.h @@ -27,145 +27,145 @@ // R1 = 0 Ohm // R2 = 4700 Ohm const short temptable_71[][2] PROGMEM = { - { 35 * OVERSAMPLENR, 300 }, - { 51 * OVERSAMPLENR, 270 }, - { 54 * OVERSAMPLENR, 265 }, - { 58 * OVERSAMPLENR, 260 }, - { 59 * OVERSAMPLENR, 258 }, - { 61 * OVERSAMPLENR, 256 }, - { 63 * OVERSAMPLENR, 254 }, - { 64 * OVERSAMPLENR, 252 }, - { 66 * OVERSAMPLENR, 250 }, - { 67 * OVERSAMPLENR, 249 }, - { 68 * OVERSAMPLENR, 248 }, - { 69 * OVERSAMPLENR, 247 }, - { 70 * OVERSAMPLENR, 246 }, - { 71 * OVERSAMPLENR, 245 }, - { 72 * OVERSAMPLENR, 244 }, - { 73 * OVERSAMPLENR, 243 }, - { 74 * OVERSAMPLENR, 242 }, - { 75 * OVERSAMPLENR, 241 }, - { 76 * OVERSAMPLENR, 240 }, - { 77 * OVERSAMPLENR, 239 }, - { 78 * OVERSAMPLENR, 238 }, - { 79 * OVERSAMPLENR, 237 }, - { 80 * OVERSAMPLENR, 236 }, - { 81 * OVERSAMPLENR, 235 }, - { 82 * OVERSAMPLENR, 234 }, - { 84 * OVERSAMPLENR, 233 }, - { 85 * OVERSAMPLENR, 232 }, - { 86 * OVERSAMPLENR, 231 }, - { 87 * OVERSAMPLENR, 230 }, - { 89 * OVERSAMPLENR, 229 }, - { 90 * OVERSAMPLENR, 228 }, - { 91 * OVERSAMPLENR, 227 }, - { 92 * OVERSAMPLENR, 226 }, - { 94 * OVERSAMPLENR, 225 }, - { 95 * OVERSAMPLENR, 224 }, - { 97 * OVERSAMPLENR, 223 }, - { 98 * OVERSAMPLENR, 222 }, - { 99 * OVERSAMPLENR, 221 }, - { 101 * OVERSAMPLENR, 220 }, - { 102 * OVERSAMPLENR, 219 }, - { 104 * OVERSAMPLENR, 218 }, - { 106 * OVERSAMPLENR, 217 }, - { 107 * OVERSAMPLENR, 216 }, - { 109 * OVERSAMPLENR, 215 }, - { 110 * OVERSAMPLENR, 214 }, - { 112 * OVERSAMPLENR, 213 }, - { 114 * OVERSAMPLENR, 212 }, - { 115 * OVERSAMPLENR, 211 }, - { 117 * OVERSAMPLENR, 210 }, - { 119 * OVERSAMPLENR, 209 }, - { 121 * OVERSAMPLENR, 208 }, - { 123 * OVERSAMPLENR, 207 }, - { 125 * OVERSAMPLENR, 206 }, - { 126 * OVERSAMPLENR, 205 }, - { 128 * OVERSAMPLENR, 204 }, - { 130 * OVERSAMPLENR, 203 }, - { 132 * OVERSAMPLENR, 202 }, - { 134 * OVERSAMPLENR, 201 }, - { 136 * OVERSAMPLENR, 200 }, - { 139 * OVERSAMPLENR, 199 }, - { 141 * OVERSAMPLENR, 198 }, - { 143 * OVERSAMPLENR, 197 }, - { 145 * OVERSAMPLENR, 196 }, - { 147 * OVERSAMPLENR, 195 }, - { 150 * OVERSAMPLENR, 194 }, - { 152 * OVERSAMPLENR, 193 }, - { 154 * OVERSAMPLENR, 192 }, - { 157 * OVERSAMPLENR, 191 }, - { 159 * OVERSAMPLENR, 190 }, - { 162 * OVERSAMPLENR, 189 }, - { 164 * OVERSAMPLENR, 188 }, - { 167 * OVERSAMPLENR, 187 }, - { 170 * OVERSAMPLENR, 186 }, - { 172 * OVERSAMPLENR, 185 }, - { 175 * OVERSAMPLENR, 184 }, - { 178 * OVERSAMPLENR, 183 }, - { 181 * OVERSAMPLENR, 182 }, - { 184 * OVERSAMPLENR, 181 }, - { 187 * OVERSAMPLENR, 180 }, - { 190 * OVERSAMPLENR, 179 }, - { 193 * OVERSAMPLENR, 178 }, - { 196 * OVERSAMPLENR, 177 }, - { 199 * OVERSAMPLENR, 176 }, - { 202 * OVERSAMPLENR, 175 }, - { 205 * OVERSAMPLENR, 174 }, - { 208 * OVERSAMPLENR, 173 }, - { 212 * OVERSAMPLENR, 172 }, - { 215 * OVERSAMPLENR, 171 }, - { 219 * OVERSAMPLENR, 170 }, - { 237 * OVERSAMPLENR, 165 }, - { 256 * OVERSAMPLENR, 160 }, - { 300 * OVERSAMPLENR, 150 }, - { 351 * OVERSAMPLENR, 140 }, - { 470 * OVERSAMPLENR, 120 }, - { 504 * OVERSAMPLENR, 115 }, - { 538 * OVERSAMPLENR, 110 }, - { 552 * OVERSAMPLENR, 108 }, - { 566 * OVERSAMPLENR, 106 }, - { 580 * OVERSAMPLENR, 104 }, - { 594 * OVERSAMPLENR, 102 }, - { 608 * OVERSAMPLENR, 100 }, - { 622 * OVERSAMPLENR, 98 }, - { 636 * OVERSAMPLENR, 96 }, - { 650 * OVERSAMPLENR, 94 }, - { 664 * OVERSAMPLENR, 92 }, - { 678 * OVERSAMPLENR, 90 }, - { 712 * OVERSAMPLENR, 85 }, - { 745 * OVERSAMPLENR, 80 }, - { 758 * OVERSAMPLENR, 78 }, - { 770 * OVERSAMPLENR, 76 }, - { 783 * OVERSAMPLENR, 74 }, - { 795 * OVERSAMPLENR, 72 }, - { 806 * OVERSAMPLENR, 70 }, - { 818 * OVERSAMPLENR, 68 }, - { 829 * OVERSAMPLENR, 66 }, - { 840 * OVERSAMPLENR, 64 }, - { 850 * OVERSAMPLENR, 62 }, - { 860 * OVERSAMPLENR, 60 }, - { 870 * OVERSAMPLENR, 58 }, - { 879 * OVERSAMPLENR, 56 }, - { 888 * OVERSAMPLENR, 54 }, - { 897 * OVERSAMPLENR, 52 }, - { 905 * OVERSAMPLENR, 50 }, - { 924 * OVERSAMPLENR, 45 }, - { 940 * OVERSAMPLENR, 40 }, - { 955 * OVERSAMPLENR, 35 }, - { 967 * OVERSAMPLENR, 30 }, - { 970 * OVERSAMPLENR, 29 }, - { 972 * OVERSAMPLENR, 28 }, - { 974 * OVERSAMPLENR, 27 }, - { 976 * OVERSAMPLENR, 26 }, - { 978 * OVERSAMPLENR, 25 }, - { 980 * OVERSAMPLENR, 24 }, - { 982 * OVERSAMPLENR, 23 }, - { 984 * OVERSAMPLENR, 22 }, - { 985 * OVERSAMPLENR, 21 }, - { 987 * OVERSAMPLENR, 20 }, - { 995 * OVERSAMPLENR, 15 }, - { 1001 * OVERSAMPLENR, 10 }, - { 1006 * OVERSAMPLENR, 5 }, - { 1010 * OVERSAMPLENR, 0 } + { OV( 35), 300 }, + { OV( 51), 270 }, + { OV( 54), 265 }, + { OV( 58), 260 }, + { OV( 59), 258 }, + { OV( 61), 256 }, + { OV( 63), 254 }, + { OV( 64), 252 }, + { OV( 66), 250 }, + { OV( 67), 249 }, + { OV( 68), 248 }, + { OV( 69), 247 }, + { OV( 70), 246 }, + { OV( 71), 245 }, + { OV( 72), 244 }, + { OV( 73), 243 }, + { OV( 74), 242 }, + { OV( 75), 241 }, + { OV( 76), 240 }, + { OV( 77), 239 }, + { OV( 78), 238 }, + { OV( 79), 237 }, + { OV( 80), 236 }, + { OV( 81), 235 }, + { OV( 82), 234 }, + { OV( 84), 233 }, + { OV( 85), 232 }, + { OV( 86), 231 }, + { OV( 87), 230 }, + { OV( 89), 229 }, + { OV( 90), 228 }, + { OV( 91), 227 }, + { OV( 92), 226 }, + { OV( 94), 225 }, + { OV( 95), 224 }, + { OV( 97), 223 }, + { OV( 98), 222 }, + { OV( 99), 221 }, + { OV( 101), 220 }, + { OV( 102), 219 }, + { OV( 104), 218 }, + { OV( 106), 217 }, + { OV( 107), 216 }, + { OV( 109), 215 }, + { OV( 110), 214 }, + { OV( 112), 213 }, + { OV( 114), 212 }, + { OV( 115), 211 }, + { OV( 117), 210 }, + { OV( 119), 209 }, + { OV( 121), 208 }, + { OV( 123), 207 }, + { OV( 125), 206 }, + { OV( 126), 205 }, + { OV( 128), 204 }, + { OV( 130), 203 }, + { OV( 132), 202 }, + { OV( 134), 201 }, + { OV( 136), 200 }, + { OV( 139), 199 }, + { OV( 141), 198 }, + { OV( 143), 197 }, + { OV( 145), 196 }, + { OV( 147), 195 }, + { OV( 150), 194 }, + { OV( 152), 193 }, + { OV( 154), 192 }, + { OV( 157), 191 }, + { OV( 159), 190 }, + { OV( 162), 189 }, + { OV( 164), 188 }, + { OV( 167), 187 }, + { OV( 170), 186 }, + { OV( 172), 185 }, + { OV( 175), 184 }, + { OV( 178), 183 }, + { OV( 181), 182 }, + { OV( 184), 181 }, + { OV( 187), 180 }, + { OV( 190), 179 }, + { OV( 193), 178 }, + { OV( 196), 177 }, + { OV( 199), 176 }, + { OV( 202), 175 }, + { OV( 205), 174 }, + { OV( 208), 173 }, + { OV( 212), 172 }, + { OV( 215), 171 }, + { OV( 219), 170 }, + { OV( 237), 165 }, + { OV( 256), 160 }, + { OV( 300), 150 }, + { OV( 351), 140 }, + { OV( 470), 120 }, + { OV( 504), 115 }, + { OV( 538), 110 }, + { OV( 552), 108 }, + { OV( 566), 106 }, + { OV( 580), 104 }, + { OV( 594), 102 }, + { OV( 608), 100 }, + { OV( 622), 98 }, + { OV( 636), 96 }, + { OV( 650), 94 }, + { OV( 664), 92 }, + { OV( 678), 90 }, + { OV( 712), 85 }, + { OV( 745), 80 }, + { OV( 758), 78 }, + { OV( 770), 76 }, + { OV( 783), 74 }, + { OV( 795), 72 }, + { OV( 806), 70 }, + { OV( 818), 68 }, + { OV( 829), 66 }, + { OV( 840), 64 }, + { OV( 850), 62 }, + { OV( 860), 60 }, + { OV( 870), 58 }, + { OV( 879), 56 }, + { OV( 888), 54 }, + { OV( 897), 52 }, + { OV( 905), 50 }, + { OV( 924), 45 }, + { OV( 940), 40 }, + { OV( 955), 35 }, + { OV( 967), 30 }, + { OV( 970), 29 }, + { OV( 972), 28 }, + { OV( 974), 27 }, + { OV( 976), 26 }, + { OV( 978), 25 }, + { OV( 980), 24 }, + { OV( 982), 23 }, + { OV( 984), 22 }, + { OV( 985), 21 }, + { OV( 987), 20 }, + { OV( 995), 15 }, + { OV(1001), 10 }, + { OV(1006), 5 }, + { OV(1010), 0 } }; diff --git a/Marlin/thermistortable_75.h b/Marlin/thermistortable_75.h index 01be61146d..758c2a04b8 100644 --- a/Marlin/thermistortable_75.h +++ b/Marlin/thermistortable_75.h @@ -30,40 +30,40 @@ // temperatures are not going to be used, it is better to leave them commented out. const short temptable_75[][2] PROGMEM = { // Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor - { (short) ( 111.06 * OVERSAMPLENR ), 200 }, // v=0.542 r=571.747 res=0.501 degC/count -// { (short) ( 174.87 * OVERSAMPLENR ), 175 }, // v=0.854 r=967.950 res=0.311 degC/count These values are valid. But they serve no -// { (short) ( 191.64 * OVERSAMPLENR ), 170 }, // v=0.936 r=1082.139 res=0.284 degC/count purpose. It is better to delete them so -// { (short) ( 209.99 * OVERSAMPLENR ), 165 }, // v=1.025 r=1212.472 res=0.260 degC/count the search is quicker and get to the meaningful -// { (short) ( 230.02 * OVERSAMPLENR ), 160 }, // v=1.123 r=1361.590 res=0.239 degC/count part of the table sooner. -// { (short) ( 251.80 * OVERSAMPLENR ), 155 }, // v=1.230 r=1532.621 res=0.220 degC/count - { (short) ( 275.43 * OVERSAMPLENR ), 150 }, // v=1.345 r=1729.283 res=0.203 degC/count -// { (short) ( 300.92 * OVERSAMPLENR ), 145 }, // v=1.469 r=1956.004 res=0.189 degC/coun - { (short) ( 328.32 * OVERSAMPLENR ), 140 }, // v=1.603 r=2218.081 res=0.176 degC/count - { (short) ( 388.65 * OVERSAMPLENR ), 130 }, // v=1.898 r=2874.980 res=0.156 degC/count - { (short) ( 421.39 * OVERSAMPLENR ), 125 }, // v=2.058 r=3286.644 res=0.149 degC/count - { (short) ( 455.65 * OVERSAMPLENR ), 120 }, // v=2.225 r=3768.002 res=0.143 degC/count - { (short) ( 491.17 * OVERSAMPLENR ), 115 }, // v=2.398 r=4332.590 res=0.139 degC/count - { (short) ( 527.68 * OVERSAMPLENR ), 110 }, // v=2.577 r=4996.905 res=0.136 degC/count - { (short) ( 564.81 * OVERSAMPLENR ), 105 }, // v=2.758 r=5781.120 res=0.134 degC/count - { (short) ( 602.19 * OVERSAMPLENR ), 100 }, // v=2.940 r=6710.000 res=0.134 degC/count - { (short) ( 676.03 * OVERSAMPLENR ), 90 }, // v=3.301 r=9131.018 res=0.138 degC/count - { (short) ( 745.85 * OVERSAMPLENR ), 80 }, // v=3.642 r=12602.693 res=0.150 degC/count - { (short) ( 778.31 * OVERSAMPLENR ), 75 }, // v=3.800 r=14889.001 res=0.159 degC/count - { (short) ( 808.75 * OVERSAMPLENR ), 70 }, // v=3.949 r=17658.700 res=0.171 degC/count - { (short) ( 836.94 * OVERSAMPLENR ), 65 }, // v=4.087 r=21028.040 res=0.185 degC/count - { (short) ( 862.74 * OVERSAMPLENR ), 60 }, // v=4.213 r=25144.568 res=0.204 degC/count - { (short) ( 886.08 * OVERSAMPLENR ), 55 }, // v=4.327 r=30196.449 res=0.227 degC/count - { (short) ( 906.97 * OVERSAMPLENR ), 50 }, // v=4.429 r=36424.838 res=0.255 degC/count - { (short) ( 941.65 * OVERSAMPLENR ), 40 }, // v=4.598 r=53745.337 res=0.333 degC/count - { (short) ( 967.76 * OVERSAMPLENR ), 30 }, // v=4.725 r=80880.630 res=0.452 degC/count - { (short) ( 978.03 * OVERSAMPLENR ), 25 }, // v=4.776 r=100000.000 res=0.535 degC/count - { (short) ( 981.68 * OVERSAMPLENR ), 23 }, // v=4.793 r=109024.395 res=0.573 degC/count - { (short) ( 983.41 * OVERSAMPLENR ), 22 }, // v=4.802 r=113875.430 res=0.594 degC/count - { (short) ( 985.08 * OVERSAMPLENR ), 21 }, // v=4.810 r=118968.955 res=0.616 degC/count - { (short) ( 986.70 * OVERSAMPLENR ), 20 }, // v=4.818 r=124318.354 res=0.638 degC/count - { (short) ( 993.94 * OVERSAMPLENR ), 15 }, // v=4.853 r=155431.302 res=0.768 degC/count - { (short) ( 999.96 * OVERSAMPLENR ), 10 }, // v=4.883 r=195480.023 res=0.934 degC/count - { (short) (1008.95 * OVERSAMPLENR ), 0 } // v=4.926 r=314997.575 res=1.418 degC/count + { OV( 111.06), 200 }, // v=0.542 r=571.747 res=0.501 degC/count +// { OV( 174.87), 175 }, // v=0.854 r=967.950 res=0.311 degC/count These values are valid. But they serve no +// { OV( 191.64), 170 }, // v=0.936 r=1082.139 res=0.284 degC/count purpose. It is better to delete them so +// { OV( 209.99), 165 }, // v=1.025 r=1212.472 res=0.260 degC/count the search is quicker and get to the meaningful +// { OV( 230.02), 160 }, // v=1.123 r=1361.590 res=0.239 degC/count part of the table sooner. +// { OV( 251.80), 155 }, // v=1.230 r=1532.621 res=0.220 degC/count + { OV( 275.43), 150 }, // v=1.345 r=1729.283 res=0.203 degC/count +// { OV( 300.92), 145 }, // v=1.469 r=1956.004 res=0.189 degC/coun + { OV( 328.32), 140 }, // v=1.603 r=2218.081 res=0.176 degC/count + { OV( 388.65), 130 }, // v=1.898 r=2874.980 res=0.156 degC/count + { OV( 421.39), 125 }, // v=2.058 r=3286.644 res=0.149 degC/count + { OV( 455.65), 120 }, // v=2.225 r=3768.002 res=0.143 degC/count + { OV( 491.17), 115 }, // v=2.398 r=4332.590 res=0.139 degC/count + { OV( 527.68), 110 }, // v=2.577 r=4996.905 res=0.136 degC/count + { OV( 564.81), 105 }, // v=2.758 r=5781.120 res=0.134 degC/count + { OV( 602.19), 100 }, // v=2.940 r=6710.000 res=0.134 degC/count + { OV( 676.03), 90 }, // v=3.301 r=9131.018 res=0.138 degC/count + { OV( 745.85), 80 }, // v=3.642 r=12602.693 res=0.150 degC/count + { OV( 778.31), 75 }, // v=3.800 r=14889.001 res=0.159 degC/count + { OV( 808.75), 70 }, // v=3.949 r=17658.700 res=0.171 degC/count + { OV( 836.94), 65 }, // v=4.087 r=21028.040 res=0.185 degC/count + { OV( 862.74), 60 }, // v=4.213 r=25144.568 res=0.204 degC/count + { OV( 886.08), 55 }, // v=4.327 r=30196.449 res=0.227 degC/count + { OV( 906.97), 50 }, // v=4.429 r=36424.838 res=0.255 degC/count + { OV( 941.65), 40 }, // v=4.598 r=53745.337 res=0.333 degC/count + { OV( 967.76), 30 }, // v=4.725 r=80880.630 res=0.452 degC/count + { OV( 978.03), 25 }, // v=4.776 r=100000.000 res=0.535 degC/count + { OV( 981.68), 23 }, // v=4.793 r=109024.395 res=0.573 degC/count + { OV( 983.41), 22 }, // v=4.802 r=113875.430 res=0.594 degC/count + { OV( 985.08), 21 }, // v=4.810 r=118968.955 res=0.616 degC/count + { OV( 986.70), 20 }, // v=4.818 r=124318.354 res=0.638 degC/count + { OV( 993.94), 15 }, // v=4.853 r=155431.302 res=0.768 degC/count + { OV( 999.96), 10 }, // v=4.883 r=195480.023 res=0.934 degC/count + { OV(1008.95), 0 } // v=4.926 r=314997.575 res=1.418 degC/count }; diff --git a/Marlin/thermistortable_8.h b/Marlin/thermistortable_8.h index f1892bf8dd..2a27f7c6f5 100644 --- a/Marlin/thermistortable_8.h +++ b/Marlin/thermistortable_8.h @@ -22,24 +22,24 @@ // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) const short temptable_8[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 704 }, - { 54 * OVERSAMPLENR, 216 }, - { 107 * OVERSAMPLENR, 175 }, - { 160 * OVERSAMPLENR, 152 }, - { 213 * OVERSAMPLENR, 137 }, - { 266 * OVERSAMPLENR, 125 }, - { 319 * OVERSAMPLENR, 115 }, - { 372 * OVERSAMPLENR, 106 }, - { 425 * OVERSAMPLENR, 99 }, - { 478 * OVERSAMPLENR, 91 }, - { 531 * OVERSAMPLENR, 85 }, - { 584 * OVERSAMPLENR, 78 }, - { 637 * OVERSAMPLENR, 71 }, - { 690 * OVERSAMPLENR, 65 }, - { 743 * OVERSAMPLENR, 58 }, - { 796 * OVERSAMPLENR, 50 }, - { 849 * OVERSAMPLENR, 42 }, - { 902 * OVERSAMPLENR, 31 }, - { 955 * OVERSAMPLENR, 17 }, - { 1008 * OVERSAMPLENR, 0 } + { OV( 1), 704 }, + { OV( 54), 216 }, + { OV( 107), 175 }, + { OV( 160), 152 }, + { OV( 213), 137 }, + { OV( 266), 125 }, + { OV( 319), 115 }, + { OV( 372), 106 }, + { OV( 425), 99 }, + { OV( 478), 91 }, + { OV( 531), 85 }, + { OV( 584), 78 }, + { OV( 637), 71 }, + { OV( 690), 65 }, + { OV( 743), 58 }, + { OV( 796), 50 }, + { OV( 849), 42 }, + { OV( 902), 31 }, + { OV( 955), 17 }, + { OV(1008), 0 } }; diff --git a/Marlin/thermistortable_9.h b/Marlin/thermistortable_9.h index e3b0e7b464..2d83dd47a3 100644 --- a/Marlin/thermistortable_9.h +++ b/Marlin/thermistortable_9.h @@ -22,35 +22,35 @@ // 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) const short temptable_9[][2] PROGMEM = { - { 1 * OVERSAMPLENR, 936 }, - { 36 * OVERSAMPLENR, 300 }, - { 71 * OVERSAMPLENR, 246 }, - { 106 * OVERSAMPLENR, 218 }, - { 141 * OVERSAMPLENR, 199 }, - { 176 * OVERSAMPLENR, 185 }, - { 211 * OVERSAMPLENR, 173 }, - { 246 * OVERSAMPLENR, 163 }, - { 281 * OVERSAMPLENR, 155 }, - { 316 * OVERSAMPLENR, 147 }, - { 351 * OVERSAMPLENR, 140 }, - { 386 * OVERSAMPLENR, 134 }, - { 421 * OVERSAMPLENR, 128 }, - { 456 * OVERSAMPLENR, 122 }, - { 491 * OVERSAMPLENR, 117 }, - { 526 * OVERSAMPLENR, 112 }, - { 561 * OVERSAMPLENR, 107 }, - { 596 * OVERSAMPLENR, 102 }, - { 631 * OVERSAMPLENR, 97 }, - { 666 * OVERSAMPLENR, 92 }, - { 701 * OVERSAMPLENR, 87 }, - { 736 * OVERSAMPLENR, 81 }, - { 771 * OVERSAMPLENR, 76 }, - { 806 * OVERSAMPLENR, 70 }, - { 841 * OVERSAMPLENR, 63 }, - { 876 * OVERSAMPLENR, 56 }, - { 911 * OVERSAMPLENR, 48 }, - { 946 * OVERSAMPLENR, 38 }, - { 981 * OVERSAMPLENR, 23 }, - { 1005 * OVERSAMPLENR, 5 }, - { 1016 * OVERSAMPLENR, 0 } + { OV( 1), 936 }, + { OV( 36), 300 }, + { OV( 71), 246 }, + { OV( 106), 218 }, + { OV( 141), 199 }, + { OV( 176), 185 }, + { OV( 211), 173 }, + { OV( 246), 163 }, + { OV( 281), 155 }, + { OV( 316), 147 }, + { OV( 351), 140 }, + { OV( 386), 134 }, + { OV( 421), 128 }, + { OV( 456), 122 }, + { OV( 491), 117 }, + { OV( 526), 112 }, + { OV( 561), 107 }, + { OV( 596), 102 }, + { OV( 631), 97 }, + { OV( 666), 92 }, + { OV( 701), 87 }, + { OV( 736), 81 }, + { OV( 771), 76 }, + { OV( 806), 70 }, + { OV( 841), 63 }, + { OV( 876), 56 }, + { OV( 911), 48 }, + { OV( 946), 38 }, + { OV( 981), 23 }, + { OV(1005), 5 }, + { OV(1016), 0 } }; diff --git a/Marlin/thermistortable_998.h b/Marlin/thermistortable_998.h index 0e0be8c428..66becc7029 100644 --- a/Marlin/thermistortable_998.h +++ b/Marlin/thermistortable_998.h @@ -27,6 +27,6 @@ #endif const short temptable_998[][2] PROGMEM = { - { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE }, - { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE } + { OV( 1), DUMMY_THERMISTOR_998_VALUE }, + { OV(1023), DUMMY_THERMISTOR_998_VALUE } }; diff --git a/Marlin/thermistortable_999.h b/Marlin/thermistortable_999.h index d98018bc4b..ea45952f60 100644 --- a/Marlin/thermistortable_999.h +++ b/Marlin/thermistortable_999.h @@ -27,6 +27,6 @@ #endif const short temptable_999[][2] PROGMEM = { - { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE }, - { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE } + { OV( 1), DUMMY_THERMISTOR_999_VALUE }, + { OV(1023), DUMMY_THERMISTOR_999_VALUE } }; diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index 164afa5ea2..6a19c9cf19 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -27,6 +27,7 @@ #include "macros.h" #define OVERSAMPLENR 16 +#define OV(N) int16_t((N)*(OVERSAMPLENR)) #define ANY_THERMISTOR_IS(n) (THERMISTORHEATER_0 == n || THERMISTORHEATER_1 == n || THERMISTORHEATER_2 == n || THERMISTORHEATER_3 == n || THERMISTORHEATER_4 == n || THERMISTORBED == n) @@ -38,7 +39,7 @@ #define PtB -5.775E-7 #define PtRt(T,R0) ((R0)*(1.0+(PtA)*(T)+(PtB)*(T)*(T))) #define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1)) -#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T }, +#define PtLine(T,R0,Rup) { OV(PtAdVal(T,R0,Rup)), T }, #if ANY_THERMISTOR_IS(1) // 100k bed thermistor #include "thermistortable_1.h" diff --git a/Marlin/tmc_macros.h b/Marlin/tmc_macros.h new file mode 100644 index 0000000000..b98c460e0b --- /dev/null +++ b/Marlin/tmc_macros.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 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 . + * + */ +#ifndef TMC_MACROS_H +#define TMC_MACROS_H + + // Trinamic Stepper Drivers + #define HAS_TRINAMIC (ENABLED(HAVE_TMC2130) || ENABLED(HAVE_TMC2208) || ENABLED(IS_TRAMS)) + #define X_IS_TRINAMIC (ENABLED( X_IS_TMC2130) || ENABLED( X_IS_TMC2208) || ENABLED(IS_TRAMS)) + #define X2_IS_TRINAMIC (ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208)) + #define Y_IS_TRINAMIC (ENABLED( Y_IS_TMC2130) || ENABLED( Y_IS_TMC2208) || ENABLED(IS_TRAMS)) + #define Y2_IS_TRINAMIC (ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208)) + #define Z_IS_TRINAMIC (ENABLED( Z_IS_TMC2130) || ENABLED( Z_IS_TMC2208) || ENABLED(IS_TRAMS)) + #define Z2_IS_TRINAMIC (ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208)) + #define E0_IS_TRINAMIC (ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208) || ENABLED(IS_TRAMS)) + #define E1_IS_TRINAMIC (ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208)) + #define E2_IS_TRINAMIC (ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208)) + #define E3_IS_TRINAMIC (ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208)) + #define E4_IS_TRINAMIC (ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208)) + +#endif diff --git a/Marlin/types.h b/Marlin/types.h index 8ab7beebea..e4f4ce197f 100644 --- a/Marlin/types.h +++ b/Marlin/types.h @@ -25,4 +25,9 @@ typedef unsigned long millis_t; +typedef struct { + int8_t x_index, y_index; + float distance; // When populated, the distance from the search location +} mesh_index_pair; + #endif diff --git a/Marlin/ubl.cpp b/Marlin/ubl.cpp index 9805aff3fc..11a2a22235 100644 --- a/Marlin/ubl.cpp +++ b/Marlin/ubl.cpp @@ -28,18 +28,7 @@ #include "ubl.h" #include "hex_print_routines.h" #include "temperature.h" - - extern Planner planner; - - /** - * These support functions allow the use of large bit arrays of flags that take very - * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration - * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed - * in the future. - */ - void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y) { CBI(bits[y], x); } - void bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { SBI(bits[y], x); } - bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { return TEST(bits[y], x); } + #include "planner.h" uint8_t ubl_cnt = 0; @@ -48,7 +37,7 @@ void unified_bed_leveling::report_state() { echo_name(); SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " "); - if (!state.active) SERIAL_PROTOCOLPGM("in"); + if (!planner.leveling_active) SERIAL_PROTOCOLPGM("in"); SERIAL_PROTOCOLLNPGM("active."); safe_delay(50); } @@ -62,44 +51,96 @@ safe_delay(10); } - ubl_state unified_bed_leveling::state; + #if ENABLED(UBL_DEVEL_DEBUGGING) - float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], - unified_bed_leveling::last_specified_z; + static void debug_echo_axis(const AxisEnum axis) { + if (current_position[axis] == destination[axis]) + SERIAL_ECHOPGM("-------------"); + else + SERIAL_ECHO_F(destination[X_AXIS], 6); + } + + void debug_current_and_destination(const char *title) { + + // if the title message starts with a '!' it is so important, we are going to + // ignore the status of the g26_debug_flag + if (*title != '!' && !g26_debug_flag) return; + + const float de = destination[E_AXIS] - current_position[E_AXIS]; + + if (de == 0.0) return; // Printing moves only + + const float dx = destination[X_AXIS] - current_position[X_AXIS], + dy = destination[Y_AXIS] - current_position[Y_AXIS], + xy_dist = HYPOT(dx, dy); + + if (xy_dist == 0.0) return; + + SERIAL_ECHOPGM(" fpmm="); + const float fpmm = de / xy_dist; + SERIAL_ECHO_F(fpmm, 6); + + SERIAL_ECHOPGM(" current=( "); + SERIAL_ECHO_F(current_position[X_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[Y_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[Z_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[E_AXIS], 6); + SERIAL_ECHOPGM(" ) destination=( "); + debug_echo_axis(X_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(Y_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(Z_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(E_AXIS); + SERIAL_ECHOPGM(" ) "); + SERIAL_ECHO(title); + SERIAL_EOL(); + + } + + #endif // UBL_DEVEL_DEBUGGING + + int8_t unified_bed_leveling::storage_slot; + + float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; // 15 is the maximum nubmer of grid points supported + 1 safety margin for now, // until determinism prevails constexpr float unified_bed_leveling::_mesh_index_to_xpos[16], unified_bed_leveling::_mesh_index_to_ypos[16]; - bool unified_bed_leveling::g26_debug_flag = false, - unified_bed_leveling::has_control_of_lcd_panel = false; + #if ENABLED(ULTIPANEL) + bool unified_bed_leveling::lcd_map_control = false; + #endif volatile int unified_bed_leveling::encoder_diff; unified_bed_leveling::unified_bed_leveling() { - ubl_cnt++; // Debug counter to insure we only have one UBL object present in memory. We can eliminate this (and all references to ubl_cnt) very soon. + ubl_cnt++; // Debug counter to ensure we only have one UBL object present in memory. We can eliminate this (and all references to ubl_cnt) very soon. reset(); } void unified_bed_leveling::reset() { + const bool was_enabled = planner.leveling_active; set_bed_leveling_enabled(false); - state.z_offset = 0; - state.storage_slot = -1; + storage_slot = -1; #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - planner.z_fade_height = 10.0; + planner.set_z_fade_height(10.0); #endif ZERO(z_values); - last_specified_z = -999.9; + if (was_enabled) report_current_position(); } void unified_bed_leveling::invalidate() { set_bed_leveling_enabled(false); - state.z_offset = 0; set_all_mesh_points_to_value(NAN); } - void unified_bed_leveling::set_all_mesh_points_to_value(float value) { + void unified_bed_leveling::set_all_mesh_points_to_value(const float value) { for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) { for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { z_values[x][y] = value; @@ -122,9 +163,9 @@ SERIAL_ECHO_SP(spaces + 3); serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1); SERIAL_EOL(); - serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MAX_Y); + serial_echo_xy(MESH_MIN_X, MESH_MAX_Y); SERIAL_ECHO_SP(spaces); - serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MAX_Y); + serial_echo_xy(MESH_MAX_X, MESH_MAX_Y); SERIAL_EOL(); } else { @@ -171,9 +212,9 @@ } if (map_type == 0) { - serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MIN_Y); + serial_echo_xy(MESH_MIN_X, MESH_MIN_Y); SERIAL_ECHO_SP(spaces + 4); - serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MIN_Y); + serial_echo_xy(MESH_MAX_X, MESH_MIN_Y); SERIAL_EOL(); serial_echo_xy(0, 0); SERIAL_ECHO_SP(spaces + 5); @@ -186,7 +227,7 @@ uint8_t error_flag = 0; if (settings.calc_num_meshes() < 1) { - SERIAL_PROTOCOLLNPGM("?Insufficient EEPROM storage for a mesh of this size."); + SERIAL_PROTOCOLLNPGM("?Mesh too big for EEPROM."); error_flag++; } diff --git a/Marlin/ubl.h b/Marlin/ubl.h index e11c743b4d..754e387dc3 100644 --- a/Marlin/ubl.h +++ b/Marlin/ubl.h @@ -26,6 +26,9 @@ #include "MarlinConfig.h" #if ENABLED(AUTO_BED_LEVELING_UBL) + + //#define UBL_DEVEL_DEBUGGING + #include "Marlin.h" #include "planner.h" #include "math.h" @@ -39,20 +42,13 @@ #define USE_NOZZLE_AS_REFERENCE 0 #define USE_PROBE_AS_REFERENCE 1 - typedef struct { - int8_t x_index, y_index; - float distance; // When populated, the distance from the search location - } mesh_index_pair; - - // ubl.cpp - - void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y); - void bit_set(uint16_t bits[16], uint8_t x, uint8_t y); - bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y); - // ubl_motion.cpp - void debug_current_and_destination(const char * const title); + #if ENABLED(UBL_DEVEL_DEBUGGING) + void debug_current_and_destination(const char * const title); + #else + FORCE_INLINE void debug_current_and_destination(const char * const title) { UNUSED(title); } + #endif // ubl_G29.cpp @@ -61,7 +57,6 @@ // External references char *ftostr43sign(const float&, char); - bool ubl_lcd_clicked(); void home_all_axes(); extern uint8_t ubl_cnt; @@ -73,20 +68,12 @@ void lcd_quick_feedback(); #endif - #define MESH_X_DIST (float(UBL_MESH_MAX_X - (UBL_MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1)) - #define MESH_Y_DIST (float(UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1)) - - typedef struct { - bool active = false; - float z_offset = 0.0; - int8_t storage_slot = -1; - } ubl_state; + #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1)) + #define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1)) class unified_bed_leveling { private: - static float last_specified_z; - static int g29_verbose_level, g29_phase_value, g29_repetition_cnt, @@ -101,53 +88,26 @@ static int g29_grid_size; #endif - #if ENABLED(UBL_G26_MESH_VALIDATION) - static float g26_extrusion_multiplier, - g26_retraction_multiplier, - g26_nozzle, - g26_filament_diameter, - g26_prime_length, - g26_x_pos, g26_y_pos, - g26_ooze_amount, - g26_layer_height; - static int16_t g26_bed_temp, - g26_hotend_temp, - g26_repeats; - static int8_t g26_prime_flag; - static bool g26_continue_with_closest, g26_keep_heaters_on; + #if ENABLED(NEWPANEL) + static void move_z_with_encoder(const float &multiplier); + static float measure_point_with_encoder(); + static float measure_business_card_thickness(const float&); + static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); + static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map); #endif - static float measure_point_with_encoder(); - static float measure_business_card_thickness(float); static bool g29_parameter_parsing(); static void find_mean_mesh_height(); static void shift_mesh_height(); - static void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest); - static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); + static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest); static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3); static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map); static void g29_what_command(); static void g29_eeprom_dump(); static void g29_compare_current_mesh_to_stored_mesh(); - static void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map); static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); static void smart_fill_mesh(); - #if ENABLED(UBL_G26_MESH_VALIDATION) - static bool exit_from_g26(); - static bool parse_G26_parameters(); - static void G26_line_to_destination(const float &feed_rate); - static mesh_index_pair find_closest_circle_to_print(const float&, const float&); - static bool look_for_lines_to_connect(); - static bool turn_on_heaters(); - static bool prime_nozzle(); - static void retract_filament(const float where[XYZE]); - static void recover_filament(const float where[XYZE]); - static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&); - static void move_to(const float&, const float&, const float&, const float&); - inline static void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); } - #endif - public: static void echo_name(); @@ -155,48 +115,46 @@ static void save_ubl_active_state_and_disable(); static void restore_ubl_active_state_and_leave(); static void display_map(const int); - static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16], bool); + static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]); + static mesh_index_pair find_furthest_invalid_mesh_point(); static void reset(); static void invalidate(); - static void set_all_mesh_points_to_value(float); + static void set_all_mesh_points_to_value(const float); static bool sanity_check(); static void G29() _O0; // O0 for no optimization static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560 - - #if ENABLED(UBL_G26_MESH_VALIDATION) - static void G26(); - #endif - - static ubl_state state; + static int8_t storage_slot; static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; // 15 is the maximum nubmer of grid points supported + 1 safety margin for now, // until determinism prevails constexpr static float _mesh_index_to_xpos[16] PROGMEM = { - UBL_MESH_MIN_X + 0 * (MESH_X_DIST), UBL_MESH_MIN_X + 1 * (MESH_X_DIST), - UBL_MESH_MIN_X + 2 * (MESH_X_DIST), UBL_MESH_MIN_X + 3 * (MESH_X_DIST), - UBL_MESH_MIN_X + 4 * (MESH_X_DIST), UBL_MESH_MIN_X + 5 * (MESH_X_DIST), - UBL_MESH_MIN_X + 6 * (MESH_X_DIST), UBL_MESH_MIN_X + 7 * (MESH_X_DIST), - UBL_MESH_MIN_X + 8 * (MESH_X_DIST), UBL_MESH_MIN_X + 9 * (MESH_X_DIST), - UBL_MESH_MIN_X + 10 * (MESH_X_DIST), UBL_MESH_MIN_X + 11 * (MESH_X_DIST), - UBL_MESH_MIN_X + 12 * (MESH_X_DIST), UBL_MESH_MIN_X + 13 * (MESH_X_DIST), - UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST) + MESH_MIN_X + 0 * (MESH_X_DIST), MESH_MIN_X + 1 * (MESH_X_DIST), + MESH_MIN_X + 2 * (MESH_X_DIST), MESH_MIN_X + 3 * (MESH_X_DIST), + MESH_MIN_X + 4 * (MESH_X_DIST), MESH_MIN_X + 5 * (MESH_X_DIST), + MESH_MIN_X + 6 * (MESH_X_DIST), MESH_MIN_X + 7 * (MESH_X_DIST), + MESH_MIN_X + 8 * (MESH_X_DIST), MESH_MIN_X + 9 * (MESH_X_DIST), + MESH_MIN_X + 10 * (MESH_X_DIST), MESH_MIN_X + 11 * (MESH_X_DIST), + MESH_MIN_X + 12 * (MESH_X_DIST), MESH_MIN_X + 13 * (MESH_X_DIST), + MESH_MIN_X + 14 * (MESH_X_DIST), MESH_MIN_X + 15 * (MESH_X_DIST) }; constexpr static float _mesh_index_to_ypos[16] PROGMEM = { - UBL_MESH_MIN_Y + 0 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 1 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 2 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 3 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 4 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 5 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 6 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 7 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 8 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 9 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 10 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 11 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 12 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 13 * (MESH_Y_DIST), - UBL_MESH_MIN_Y + 14 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 15 * (MESH_Y_DIST) + MESH_MIN_Y + 0 * (MESH_Y_DIST), MESH_MIN_Y + 1 * (MESH_Y_DIST), + MESH_MIN_Y + 2 * (MESH_Y_DIST), MESH_MIN_Y + 3 * (MESH_Y_DIST), + MESH_MIN_Y + 4 * (MESH_Y_DIST), MESH_MIN_Y + 5 * (MESH_Y_DIST), + MESH_MIN_Y + 6 * (MESH_Y_DIST), MESH_MIN_Y + 7 * (MESH_Y_DIST), + MESH_MIN_Y + 8 * (MESH_Y_DIST), MESH_MIN_Y + 9 * (MESH_Y_DIST), + MESH_MIN_Y + 10 * (MESH_Y_DIST), MESH_MIN_Y + 11 * (MESH_Y_DIST), + MESH_MIN_Y + 12 * (MESH_Y_DIST), MESH_MIN_Y + 13 * (MESH_Y_DIST), + MESH_MIN_Y + 14 * (MESH_Y_DIST), MESH_MIN_Y + 15 * (MESH_Y_DIST) }; - static bool g26_debug_flag, has_control_of_lcd_panel; + #if ENABLED(ULTIPANEL) + static bool lcd_map_control; + #endif static volatile int encoder_diff; // Volatile because it's changed at interrupt time. @@ -205,14 +163,14 @@ FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; } static int8_t get_cell_index_x(const float &x) { - const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST)); + const int8_t cx = (x - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)); return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1); // -1 is appropriate if we want all movement to the X_MAX } // position. But with this defined this way, it is possible // to extrapolate off of this point even further out. Probably // that is OK because something else should be keeping that from // happening and should not be worried about at this level. static int8_t get_cell_index_y(const float &y) { - const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST)); + const int8_t cy = (y - (MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST)); return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1); // -1 is appropriate if we want all movement to the Y_MAX } // position. But with this defined this way, it is possible // to extrapolate off of this point even further out. Probably @@ -220,12 +178,12 @@ // happening and should not be worried about at this level. static int8_t find_closest_x_index(const float &x) { - const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST)); + const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST)); return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1; } static int8_t find_closest_y_index(const float &y) { - const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST)); + const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST)); return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1; } @@ -252,41 +210,53 @@ * z_correction_for_x_on_horizontal_mesh_line is an optimization for * the case where the printer is making a vertical line that only crosses horizontal mesh lines. */ - inline static float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) { - if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) { - serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") ); - SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0); - SERIAL_ECHOPAIR(",x1_i=", x1_i); - SERIAL_ECHOPAIR(",yi=", yi); - SERIAL_CHAR(')'); - SERIAL_EOL(); + inline static float z_correction_for_x_on_horizontal_mesh_line(const float &rx0, const int x1_i, const int yi) { + if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1_i") : PSTR("yi") ); + SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0); + SERIAL_ECHOPAIR(",x1_i=", x1_i); + SERIAL_ECHOPAIR(",yi=", yi); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif return NAN; } - const float xratio = (RAW_X_POSITION(lx0) - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)), + const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)), z1 = z_values[x1_i][yi]; - return z1 + xratio * (z_values[x1_i + 1][yi] - z1); + return z1 + xratio * (z_values[min(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array + // If it is, it is clamped to the last element of the + // z_values[][] array and no correction is applied. } // // See comments above for z_correction_for_x_on_horizontal_mesh_line // - inline static float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) { - if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 2)) { - serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") ); - SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0); - SERIAL_ECHOPAIR(", xi=", xi); - SERIAL_ECHOPAIR(", y1_i=", y1_i); - SERIAL_CHAR(')'); - SERIAL_EOL(); + inline static float z_correction_for_y_on_vertical_mesh_line(const float &ry0, const int xi, const int y1_i) { + if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("y1_i") ); + SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0); + SERIAL_ECHOPAIR(", xi=", xi); + SERIAL_ECHOPAIR(", y1_i=", y1_i); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif return NAN; } - const float yratio = (RAW_Y_POSITION(ly0) - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)), + const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)), z1 = z_values[xi][y1_i]; - return z1 + yratio * (z_values[xi][y1_i + 1] - z1); + return z1 + yratio * (z_values[xi][min(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array + // If it is, it is clamped to the last element of the + // z_values[][] array and no correction is applied. } /** @@ -295,41 +265,27 @@ * Z-Height at both ends. Then it does a linear interpolation of these heights based * on the Y position within the cell. */ - static float get_z_correction(const float &lx0, const float &ly0) { - const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)), - cy = get_cell_index_y(RAW_Y_POSITION(ly0)); + static float get_z_correction(const float &rx0, const float &ry0) { + const int8_t cx = get_cell_index_x(rx0), + cy = get_cell_index_y(ry0); // return values are clamped - if (!WITHIN(cx, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(cy, 0, GRID_MAX_POINTS_Y - 2)) { - - SERIAL_ECHOPAIR("? in get_z_correction(lx0=", lx0); - SERIAL_ECHOPAIR(", ly0=", ly0); - SERIAL_CHAR(')'); - SERIAL_EOL(); - - #if ENABLED(ULTRA_LCD) - strcpy(lcd_status_message, "get_z_correction() indexes out of range."); - lcd_quick_feedback(); - #endif - return NAN; // this used to return state.z_offset - } - - const float z1 = calc_z0(RAW_X_POSITION(lx0), + const float z1 = calc_z0(rx0, mesh_index_to_xpos(cx), z_values[cx][cy], - mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy]); + mesh_index_to_xpos(cx + 1), z_values[min(cx, GRID_MAX_POINTS_X - 2) + 1][cy]); - const float z2 = calc_z0(RAW_X_POSITION(lx0), - mesh_index_to_xpos(cx), z_values[cx][cy + 1], - mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy + 1]); + const float z2 = calc_z0(rx0, + mesh_index_to_xpos(cx), z_values[cx][min(cy, GRID_MAX_POINTS_Y - 2) + 1], + mesh_index_to_xpos(cx + 1), z_values[min(cx, GRID_MAX_POINTS_X - 2) + 1][min(cy, GRID_MAX_POINTS_Y - 2) + 1]); - float z0 = calc_z0(RAW_Y_POSITION(ly0), + float z0 = calc_z0(ry0, mesh_index_to_ypos(cy), z1, mesh_index_to_ypos(cy + 1), z2); #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(MESH_ADJUST)) { - SERIAL_ECHOPAIR(" raw get_z_correction(", lx0); + SERIAL_ECHOPAIR(" raw get_z_correction(", rx0); SERIAL_CHAR(','); - SERIAL_ECHO(ly0); + SERIAL_ECHO(ry0); SERIAL_ECHOPGM(") = "); SERIAL_ECHO_F(z0, 6); } @@ -351,61 +307,47 @@ #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(MESH_ADJUST)) { - SERIAL_ECHOPAIR("??? Yikes! NAN in get_z_correction(", lx0); + SERIAL_ECHOPAIR("??? Yikes! NAN in get_z_correction(", rx0); SERIAL_CHAR(','); - SERIAL_ECHO(ly0); + SERIAL_ECHO(ry0); SERIAL_CHAR(')'); SERIAL_EOL(); } #endif } - return z0; // there used to be a +state.z_offset on this line + return z0; } - /** - * This function sets the Z leveling fade factor based on the given Z height, - * only re-calculating when necessary. - * - * Returns 1.0 if planner.z_fade_height is 0.0. - * Returns 0.0 if Z is past the specified 'Fade Height'. - */ - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - static inline float fade_scaling_factor_for_z(const float &lz) { - if (planner.z_fade_height == 0.0) return 1.0; - static float fade_scaling_factor = 1.0; - const float rz = RAW_Z_POSITION(lz); - if (last_specified_z != rz) { - last_specified_z = rz; - fade_scaling_factor = - rz < planner.z_fade_height - ? 1.0 - (rz * planner.inverse_z_fade_height) - : 0.0; - } - return fade_scaling_factor; - } - #else - FORCE_INLINE static float fade_scaling_factor_for_z(const float &lz) { return 1.0; } - #endif - FORCE_INLINE static float mesh_index_to_xpos(const uint8_t i) { - return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : UBL_MESH_MIN_X + i * (MESH_X_DIST); + return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST); } FORCE_INLINE static float mesh_index_to_ypos(const uint8_t i) { - return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : UBL_MESH_MIN_Y + i * (MESH_Y_DIST); + return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST); } - static bool prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate); - static void line_to_destination_cartesian(const float &fr, uint8_t e); + #if UBL_SEGMENTED + static bool prepare_segmented_line_to(const float (&rtarget)[XYZE], const float &feedrate); + #else + static void line_to_destination_cartesian(const float &fr, const uint8_t e); + #endif + #define _CMPZ(a,b) (z_values[a][b] == z_values[a][b+1]) + #define CMPZ(a) (_CMPZ(a, 0) && _CMPZ(a, 1)) + #define ZZER(a) (z_values[a][0] == 0) + + FORCE_INLINE bool mesh_is_valid() { + return !( + ( CMPZ(0) && CMPZ(1) && CMPZ(2) // adjacent z values all equal? + && ZZER(0) && ZZER(1) && ZZER(2) // all zero at the edge? + ) + || isnan(z_values[0][0]) + ); + } }; // class unified_bed_leveling extern unified_bed_leveling ubl; - #if ENABLED(UBL_G26_MESH_VALIDATION) - FORCE_INLINE void gcode_G26() { ubl.G26(); } - #endif - FORCE_INLINE void gcode_G29() { ubl.G29(); } #endif // AUTO_BED_LEVELING_UBL diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index 3ec507a685..6b56ffafc5 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -32,6 +32,7 @@ #include "stepper.h" #include "planner.h" #include "gcode.h" + #include "bitmap_flags.h" #include #include "least_squares_fit.h" @@ -42,7 +43,7 @@ #if ENABLED(NEWPANEL) void lcd_return_to_status(); - void lcd_mesh_edit_setup(float initial); + void lcd_mesh_edit_setup(const float initial); float lcd_mesh_edit(); void lcd_z_offset_edit_setup(float); extern void _lcd_ubl_output_map_lcd(); @@ -51,11 +52,12 @@ extern float meshedit_done; extern long babysteps_done; - extern float probe_pt(const float &lx, const float &ly, const bool, const uint8_t, const bool=true); + extern float probe_pt(const float &rx, const float &ry, const bool, const uint8_t, const bool=true); extern bool set_probe_deployed(bool); extern void set_bed_leveling_enabled(bool); + typedef void (*screenFunc_t)(); - extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder = 0); + extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder=0); #define SIZE_OF_LITTLE_RAISE 1 #define BIG_RAISE_NOT_NEEDED 0 @@ -307,8 +309,7 @@ void unified_bed_leveling::G29() { if (!settings.calc_num_meshes()) { - SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it"); - SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n"); + SERIAL_PROTOCOLLNPGM("?Enable EEPROM and init with M502, M500.\n"); return; } @@ -332,7 +333,7 @@ else { while (g29_repetition_cnt--) { if (cnt > 20) { cnt = 0; idle(); } - const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL, false); + const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL); if (location.x_index < 0) { // No more REACHABLE mesh points to invalidate, so we ASSUME the user // meant to invalidate the ENTIRE mesh, which cannot be done with @@ -392,11 +393,11 @@ restore_ubl_active_state_and_leave(); } else { // grid_size == 0 : A 3-Point leveling has been requested - float z3, z2, z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level); + float z3, z2, z1 = probe_pt(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y, false, g29_verbose_level); if (!isnan(z1)) { - z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level); + z2 = probe_pt(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y, false, g29_verbose_level); if (!isnan(z2)) - z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level); + z3 = probe_pt(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y, true, g29_verbose_level); } if (isnan(z1) || isnan(z2) || isnan(z3)) { // probe_pt will return NAN if unreachable @@ -410,11 +411,11 @@ // its height is.) save_ubl_active_state_and_disable(); - z1 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y)) /* + zprobe_zoffset */ ; - z2 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y)) /* + zprobe_zoffset */ ; - z3 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y)) /* + zprobe_zoffset */ ; + z1 -= get_z_correction(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y) /* + zprobe_zoffset */ ; + z2 -= get_z_correction(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y) /* + zprobe_zoffset */ ; + z3 -= get_z_correction(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y) /* + zprobe_zoffset */ ; - do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); + do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y))); tilt_mesh_based_on_3pts(z1, z2, z3); restore_ubl_active_state_and_leave(); } @@ -423,8 +424,8 @@ #endif // HAS_BED_PROBE if (parser.seen('P')) { - if (WITHIN(g29_phase_value, 0, 1) && state.storage_slot == -1) { - state.storage_slot = 0; + if (WITHIN(g29_phase_value, 0, 1) && storage_slot == -1) { + storage_slot = 0; SERIAL_PROTOCOLLNPGM("Default storage slot 0 selected."); } @@ -466,6 +467,7 @@ // SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations."); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + if (!g29_x_flag && !g29_y_flag) { /** * Use a good default location for the path. @@ -496,7 +498,7 @@ } } - if (!position_is_reachable_xy(g29_x_pos, g29_y_pos)) { + if (!position_is_reachable(g29_x_pos, g29_y_pos)) { SERIAL_PROTOCOLLNPGM("XY outside printable radius."); return; } @@ -528,7 +530,7 @@ } else { while (g29_repetition_cnt--) { // this only populates reachable mesh points near - const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL, false); + const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL); if (location.x_index < 0) { // No more REACHABLE INVALID mesh points to populate, so we ASSUME // user meant to populate ALL INVALID mesh points to value @@ -603,7 +605,7 @@ // if (parser.seen('L')) { // Load Current Mesh Data - g29_storage_slot = parser.has_value() ? parser.value_int() : state.storage_slot; + g29_storage_slot = parser.has_value() ? parser.value_int() : storage_slot; int16_t a = settings.calc_num_meshes(); @@ -619,7 +621,7 @@ } settings.load_mesh(g29_storage_slot); - state.storage_slot = g29_storage_slot; + storage_slot = g29_storage_slot; SERIAL_PROTOCOLLNPGM("Done."); } @@ -629,7 +631,7 @@ // if (parser.seen('S')) { // Store (or Save) Current Mesh Data - g29_storage_slot = parser.has_value() ? parser.value_int() : state.storage_slot; + g29_storage_slot = parser.has_value() ? parser.value_int() : storage_slot; if (g29_storage_slot == -1) { // Special case, we are going to 'Export' the mesh to the SERIAL_ECHOLNPGM("G29 I 999"); // host in a form it can be reconstructed on a different machine @@ -661,72 +663,13 @@ } settings.store_mesh(g29_storage_slot); - state.storage_slot = g29_storage_slot; + storage_slot = g29_storage_slot; SERIAL_PROTOCOLLNPGM("Done."); } if (parser.seen('T')) - display_map(parser.has_value() ? parser.value_int() : 0); - - /** - * This code may not be needed... Prepare for its removal... - * - */ - #if 0 - if (parser.seen('Z')) { - if (parser.has_value()) - state.z_offset = parser.value_float(); // do the simple case. Just lock in the specified value - else { - save_ubl_active_state_and_disable(); - //float measured_z = probe_pt(g29_x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, g29_y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, ProbeDeployAndStow, g29_verbose_level); - - has_control_of_lcd_panel = true; // Grab the LCD Hardware - float measured_z = 1.5; - do_blocking_move_to_z(measured_z); // Get close to the bed, but leave some space so we don't damage anything - // The user is not going to be locking in a new Z-Offset very often so - // it won't be that painful to spin the Encoder Wheel for 1.5mm - lcd_refresh(); - lcd_z_offset_edit_setup(measured_z); - - KEEPALIVE_STATE(PAUSED_FOR_USER); - - do { - measured_z = lcd_z_offset_edit(); - idle(); - do_blocking_move_to_z(measured_z); - } while (!ubl_lcd_clicked()); - - has_control_of_lcd_panel = true; // There is a race condition for the encoder click. - // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) - // or here. So, until we are done looking for a long encoder press, - // we need to take control of the panel - - KEEPALIVE_STATE(IN_HANDLER); - - lcd_return_to_status(); - - const millis_t nxt = millis() + 1500UL; - while (ubl_lcd_clicked()) { // debounce and watch for abort - idle(); - if (ELAPSED(millis(), nxt)) { - SERIAL_PROTOCOLLNPGM("\nZ-Offset Adjustment Stopped."); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - LCD_MESSAGEPGM(MSG_UBL_Z_OFFSET_STOPPED); - restore_ubl_active_state_and_leave(); - goto LEAVE; - } - } - has_control_of_lcd_panel = false; - safe_delay(20); // We don't want any switch noise. - - state.z_offset = measured_z; - - lcd_refresh(); - restore_ubl_active_state_and_leave(); - } - } - #endif + display_map(g29_map_type); LEAVE: @@ -734,8 +677,7 @@ lcd_reset_alert_level(); LCD_MESSAGEPGM(""); lcd_quick_feedback(); - - has_control_of_lcd_panel = false; + lcd_external_control = false; #endif return; @@ -786,54 +728,83 @@ z_values[x][y] += g29_constant; } + #if ENABLED(NEWPANEL) + + typedef void (*clickFunc_t)(); + + bool click_and_hold(const clickFunc_t func=NULL) { + if (is_lcd_clicked()) { + lcd_quick_feedback(); + const millis_t nxt = millis() + 1500UL; + while (is_lcd_clicked()) { // Loop while the encoder is pressed. Uses hardware flag! + idle(); // idle, of course + if (ELAPSED(millis(), nxt)) { // After 1.5 seconds + lcd_quick_feedback(); + if (func) (*func)(); + wait_for_release(); + safe_delay(50); // Debounce the Encoder wheel + return true; + } + } + } + return false; + } + + #endif // NEWPANEL + #if HAS_BED_PROBE /** * Probe all invalidated locations of the mesh that can be reached by the probe. * This attempts to fill in locations closest to the nozzle's start location first. */ - void unified_bed_leveling::probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) { + void unified_bed_leveling::probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) { mesh_index_pair location; - has_control_of_lcd_panel = true; + #if ENABLED(NEWPANEL) + lcd_external_control = true; + #endif + save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe DEPLOY_PROBE(); uint16_t max_iterations = GRID_MAX_POINTS; do { + if (do_ubl_mesh_map) display_map(g29_map_type); + #if ENABLED(NEWPANEL) - if (ubl_lcd_clicked()) { + if (is_lcd_clicked()) { SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); lcd_quick_feedback(); STOW_PROBE(); - while (ubl_lcd_clicked()) idle(); - has_control_of_lcd_panel = false; + wait_for_release(); + lcd_external_control = false; restore_ubl_active_state_and_leave(); - safe_delay(50); // Debounce the Encoder wheel return; } #endif - location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_PROBE_AS_REFERENCE, NULL, close_or_far); + if (close_or_far) + location = find_furthest_invalid_mesh_point(); + else + location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_PROBE_AS_REFERENCE, NULL); if (location.x_index >= 0) { // mesh point found and is reachable by probe const float rawx = mesh_index_to_xpos(location.x_index), rawy = mesh_index_to_ypos(location.y_index); - const float measured_z = probe_pt(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy), stow_probe, g29_verbose_level); // TODO: Needs error handling + const float measured_z = probe_pt(rawx, rawy, stow_probe, g29_verbose_level); // TODO: Needs error handling z_values[location.x_index][location.y_index] = measured_z; } - if (do_ubl_mesh_map) display_map(g29_map_type); - } while (location.x_index >= 0 && --max_iterations); STOW_PROBE(); restore_ubl_active_state_and_leave(); do_blocking_move_to_xy( - constrain(lx - (X_PROBE_OFFSET_FROM_EXTRUDER), UBL_MESH_MIN_X, UBL_MESH_MAX_X), - constrain(ly - (Y_PROBE_OFFSET_FROM_EXTRUDER), UBL_MESH_MIN_Y, UBL_MESH_MAX_Y) + constrain(rx - (X_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_X, MESH_MAX_X), + constrain(ry - (Y_PROBE_OFFSET_FROM_EXTRUDER), MESH_MIN_Y, MESH_MAX_Y) ); } @@ -940,34 +911,36 @@ } } } + #endif // HAS_BED_PROBE #if ENABLED(NEWPANEL) - float unified_bed_leveling::measure_point_with_encoder() { - while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel - delay(50); // debounce - - KEEPALIVE_STATE(PAUSED_FOR_USER); - while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! + void unified_bed_leveling::move_z_with_encoder(const float &multiplier) { + wait_for_release(); + while (!is_lcd_clicked()) { idle(); if (encoder_diff) { - do_blocking_move_to_z(current_position[Z_AXIS] + 0.01 * float(encoder_diff)); + do_blocking_move_to_z(current_position[Z_AXIS] + float(encoder_diff) * multiplier); encoder_diff = 0; } } + } + + float unified_bed_leveling::measure_point_with_encoder() { + KEEPALIVE_STATE(PAUSED_FOR_USER); + move_z_with_encoder(0.01); KEEPALIVE_STATE(IN_HANDLER); return current_position[Z_AXIS]; } static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); } - float unified_bed_leveling::measure_business_card_thickness(float in_height) { - has_control_of_lcd_panel = true; + float unified_bed_leveling::measure_business_card_thickness(const float &in_height) { + lcd_external_control = true; save_ubl_active_state_and_disable(); // Disable bed level correction for probing - do_blocking_move_to_z(in_height); - do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); + do_blocking_move_to(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)), in_height); //, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0); stepper.synchronize(); @@ -996,47 +969,48 @@ SERIAL_PROTOCOLLNPGM("mm thick."); } - in_height = current_position[Z_AXIS]; // do manual probing at lower height - - has_control_of_lcd_panel = false; + lcd_external_control = false; restore_ubl_active_state_and_leave(); return thickness; } - void unified_bed_leveling::manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) { + void abort_manual_probe_remaining_mesh() { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + lcd_external_control = false; + KEEPALIVE_STATE(IN_HANDLER); + ubl.restore_ubl_active_state_and_leave(); + } - has_control_of_lcd_panel = true; + void unified_bed_leveling::manually_probe_remaining_mesh(const float &rx, const float &ry, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) { + + lcd_external_control = true; save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(lx, ly); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); lcd_return_to_status(); mesh_index_pair location; do { - location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_NOZZLE_AS_REFERENCE, NULL, false); + location = find_closest_mesh_point_of_type(INVALID, rx, ry, USE_NOZZLE_AS_REFERENCE, NULL); // It doesn't matter if the probe can't reach the NAN location. This is a manual probe. if (location.x_index < 0 && location.y_index < 0) continue; - const float rawx = mesh_index_to_xpos(location.x_index), - rawy = mesh_index_to_ypos(location.y_index), - xProbe = LOGICAL_X_POSITION(rawx), - yProbe = LOGICAL_Y_POSITION(rawy); + const float xProbe = mesh_index_to_xpos(location.x_index), + yProbe = mesh_index_to_ypos(location.y_index); - if (!position_is_reachable_raw_xy(rawx, rawy)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points) - - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + if (!position_is_reachable(xProbe, yProbe)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points) LCD_MESSAGEPGM(MSG_UBL_MOVING_TO_NEXT); - do_blocking_move_to_xy(xProbe, yProbe); + do_blocking_move_to(xProbe, yProbe, Z_CLEARANCE_BETWEEN_PROBES); do_blocking_move_to_z(z_clearance); KEEPALIVE_STATE(PAUSED_FOR_USER); - has_control_of_lcd_panel = true; + lcd_external_control = true; if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing @@ -1045,36 +1019,15 @@ const float z_step = 0.01; // existing behavior: 0.01mm per click, occasionally step //const float z_step = 1.0 / planner.axis_steps_per_mm[Z_AXIS]; // approx one step each click - while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel - delay(50); // debounce - while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! - idle(); - if (encoder_diff) { - do_blocking_move_to_z(current_position[Z_AXIS] + float(encoder_diff) * z_step); - encoder_diff = 0; - } - } + move_z_with_encoder(z_step); - // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is - // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This - // should be redone and compressed. - const millis_t nxt = millis() + 1500L; - while (ubl_lcd_clicked()) { // debounce and watch for abort - idle(); - if (ELAPSED(millis(), nxt)) { - SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - - #if ENABLED(NEWPANEL) - lcd_quick_feedback(); - while (ubl_lcd_clicked()) idle(); - has_control_of_lcd_panel = false; - #endif - - KEEPALIVE_STATE(IN_HANDLER); - restore_ubl_active_state_and_leave(); - return; - } + if (click_and_hold()) { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + lcd_external_control = false; + KEEPALIVE_STATE(IN_HANDLER); + restore_ubl_active_state_and_leave(); + return; } z_values[location.x_index][location.y_index] = current_position[Z_AXIS] - thick; @@ -1089,8 +1042,7 @@ restore_ubl_active_state_and_leave(); KEEPALIVE_STATE(IN_HANDLER); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - do_blocking_move_to_xy(lx, ly); + do_blocking_move_to(rx, ry, Z_CLEARANCE_DEPLOY_PROBE); } #endif // NEWPANEL @@ -1162,8 +1114,8 @@ } // If X or Y are not valid, use center of the bed values - if (!WITHIN(RAW_X_POSITION(g29_x_pos), X_MIN_BED, X_MAX_BED)) g29_x_pos = LOGICAL_X_POSITION(X_CENTER); - if (!WITHIN(RAW_Y_POSITION(g29_y_pos), Y_MIN_BED, Y_MAX_BED)) g29_y_pos = LOGICAL_Y_POSITION(Y_CENTER); + if (!WITHIN(g29_x_pos, X_MIN_BED, X_MAX_BED)) g29_x_pos = X_CENTER; + if (!WITHIN(g29_y_pos, Y_MIN_BED, Y_MAX_BED)) g29_y_pos = Y_CENTER; if (err_flag) return UBL_ERR; @@ -1209,36 +1161,39 @@ return UBL_OK; } - static int ubl_state_at_invocation = 0, - ubl_state_recursion_chk = 0; + static uint8_t ubl_state_at_invocation = 0; + + #if ENABLED(UBL_DEVEL_DEBUGGING) + static uint8_t ubl_state_recursion_chk = 0; + #endif void unified_bed_leveling::save_ubl_active_state_and_disable() { - ubl_state_recursion_chk++; - if (ubl_state_recursion_chk != 1) { - SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); - - #if ENABLED(NEWPANEL) - LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); - lcd_quick_feedback(); - #endif - - return; - } - ubl_state_at_invocation = state.active; + #if ENABLED(UBL_DEVEL_DEBUGGING) + ubl_state_recursion_chk++; + if (ubl_state_recursion_chk != 1) { + SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); + lcd_quick_feedback(); + #endif + return; + } + #endif + ubl_state_at_invocation = planner.leveling_active; set_bed_leveling_enabled(false); } void unified_bed_leveling::restore_ubl_active_state_and_leave() { - if (--ubl_state_recursion_chk) { - SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); - - #if ENABLED(NEWPANEL) - LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); - lcd_quick_feedback(); - #endif - - return; - } + #if ENABLED(UBL_DEVEL_DEBUGGING) + if (--ubl_state_recursion_chk) { + SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); + lcd_quick_feedback(); + #endif + return; + } + #endif set_bed_leveling_enabled(ubl_state_at_invocation); } @@ -1249,10 +1204,10 @@ void unified_bed_leveling::g29_what_command() { report_state(); - if (state.storage_slot == -1) + if (storage_slot == -1) SERIAL_PROTOCOLPGM("No Mesh Loaded."); else { - SERIAL_PROTOCOLPAIR("Mesh ", state.storage_slot); + SERIAL_PROTOCOLPAIR("Mesh ", storage_slot); SERIAL_PROTOCOLPGM(" Loaded."); } SERIAL_EOL(); @@ -1274,11 +1229,11 @@ SERIAL_EOL(); #endif - SERIAL_ECHOLNPAIR("UBL_MESH_MIN_X " STRINGIFY(UBL_MESH_MIN_X) "=", UBL_MESH_MIN_X); - SERIAL_ECHOLNPAIR("UBL_MESH_MIN_Y " STRINGIFY(UBL_MESH_MIN_Y) "=", UBL_MESH_MIN_Y); + SERIAL_ECHOLNPAIR("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); + SERIAL_ECHOLNPAIR("MESH_MIN_Y " STRINGIFY(MESH_MIN_Y) "=", MESH_MIN_Y); safe_delay(25); - SERIAL_ECHOLNPAIR("UBL_MESH_MAX_X " STRINGIFY(UBL_MESH_MAX_X) "=", UBL_MESH_MAX_X); - SERIAL_ECHOLNPAIR("UBL_MESH_MAX_Y " STRINGIFY(UBL_MESH_MAX_Y) "=", UBL_MESH_MAX_Y); + SERIAL_ECHOLNPAIR("MESH_MAX_X " STRINGIFY(MESH_MAX_X) "=", MESH_MAX_X); + SERIAL_ECHOLNPAIR("MESH_MAX_Y " STRINGIFY(MESH_MAX_Y) "=", MESH_MAX_Y); safe_delay(25); SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); @@ -1310,28 +1265,30 @@ SERIAL_EOL(); safe_delay(50); - SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation); - SERIAL_EOL(); - SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk); - SERIAL_EOL(); - safe_delay(50); + #if ENABLED(UBL_DEVEL_DEBUGGING) + SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk); + SERIAL_EOL(); + safe_delay(50); - SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes())); - SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes())); - safe_delay(50); + SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes())); + SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes())); + safe_delay(50); - SERIAL_PROTOCOLLNPAIR("sizeof(ubl) : ", (int)sizeof(ubl)); - SERIAL_EOL(); - SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values)); - SERIAL_EOL(); - safe_delay(25); + SERIAL_PROTOCOLLNPAIR("sizeof(ubl) : ", (int)sizeof(ubl)); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values)); + SERIAL_EOL(); + safe_delay(25); - SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes()))); - safe_delay(50); + SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes()))); + safe_delay(50); - SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes()); - SERIAL_PROTOCOLLNPGM(" meshes.\n"); - safe_delay(25); + SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes()); + SERIAL_PROTOCOLLNPGM(" meshes.\n"); + safe_delay(25); + #endif // UBL_DEVEL_DEBUGGING if (!sanity_check()) { echo_name(); @@ -1345,7 +1302,7 @@ */ void unified_bed_leveling::g29_eeprom_dump() { unsigned char cccc; - uint16_t kkkk; + unsigned int kkkk; // Needs to be of unspecfied size to compile clean on all platforms SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("EEPROM Dump:"); @@ -1355,7 +1312,7 @@ SERIAL_ECHOPGM(": "); for (uint16_t j = 0; j < 16; j++) { kkkk = i + j; - eeprom_read_block(&cccc, (void *)kkkk, 1); + eeprom_read_block(&cccc, (const void *) kkkk, sizeof(unsigned char)); print_hex_byte(cccc); SERIAL_ECHO(' '); } @@ -1401,26 +1358,90 @@ z_values[x][y] -= tmp_z_values[x][y]; } - mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], const bool far_flag) { + mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { + + bool found_a_NAN = false, found_a_real = false; + mesh_index_pair out_mesh; out_mesh.x_index = out_mesh.y_index = -1; + out_mesh.distance = -99999.99; + + for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (int8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + + if (isnan(z_values[i][j])) { // Check to see if this location holds an invalid mesh point + + const float mx = mesh_index_to_xpos(i), + my = mesh_index_to_ypos(j); + + if (!position_is_reachable_by_probe(mx, my)) // make sure the probe can get to the mesh point + continue; + + found_a_NAN = true; + + int8_t closest_x=-1, closest_y=-1; + float d1, d2 = 99999.9; + for (int8_t k = 0; k < GRID_MAX_POINTS_X; k++) { + for (int8_t l = 0; l < GRID_MAX_POINTS_Y; l++) { + if (!isnan(z_values[k][l])) { + found_a_real = true; + + // Add in a random weighting factor that scrambles the probing of the + // last half of the mesh (when every unprobed mesh point is one index + // from a probed location). + + d1 = HYPOT(i - k, j - l) + (1.0 / ((millis() % 47) + 13)); + + if (d1 < d2) { // found a closer distance from invalid mesh point at (i,j) to defined mesh point at (k,l) + d2 = d1; // found a closer location with + closest_x = i; // an assigned mesh point value + closest_y = j; + } + } + } + } + + // + // at this point d2 should have the closest defined mesh point to invalid mesh point (i,j) + // + + if (found_a_real && (closest_x >= 0) && (d2 > out_mesh.distance)) { + out_mesh.distance = d2; // found an invalid location with a greater distance + out_mesh.x_index = closest_x; // to a defined mesh point + out_mesh.y_index = closest_y; + } + } + } // for j + } // for i + + if (!found_a_real && found_a_NAN) { // if the mesh is totally unpopulated, start the probing + out_mesh.x_index = GRID_MAX_POINTS_X / 2; + out_mesh.y_index = GRID_MAX_POINTS_Y / 2; + out_mesh.distance = 1.0; + } + return out_mesh; + } + + mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &rx, const float &ry, const bool probe_as_reference, uint16_t bits[16]) { + mesh_index_pair out_mesh; + out_mesh.x_index = out_mesh.y_index = -1; + out_mesh.distance = -99999.9; // Get our reference position. Either the nozzle or probe location. - const float px = RAW_X_POSITION(lx) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0), - py = RAW_Y_POSITION(ly) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0); + const float px = rx - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0), + py = ry - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0); - float best_so_far = far_flag ? -99999.99 : 99999.99; + float best_so_far = 99999.99; - for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { - for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (int8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { if ( (type == INVALID && isnan(z_values[i][j])) // Check to see if this location holds the right thing || (type == REAL && !isnan(z_values[i][j])) - || (type == SET_IN_BITMAP && is_bit_set(bits, i, j)) + || (type == SET_IN_BITMAP && is_bitmap_set(bits, i, j)) ) { // We only get here if we found a Mesh Point of the specified type - float raw_x = RAW_CURRENT_POSITION(X), raw_y = RAW_CURRENT_POSITION(Y); const float mx = mesh_index_to_xpos(i), my = mesh_index_to_ypos(j); @@ -1428,39 +1449,18 @@ // Also for round beds, there are grid points outside the bed the nozzle can't reach. // Prune them from the list and ignore them till the next Phase (manual nozzle probing). - if (probe_as_reference ? !position_is_reachable_by_probe_raw_xy(mx, my) : !position_is_reachable_raw_xy(mx, my)) + if (probe_as_reference ? !position_is_reachable_by_probe(mx, my) : !position_is_reachable(mx, my)) continue; // Reachable. Check if it's the best_so_far location to the nozzle. - // Add in a weighting factor that considers the current location of the nozzle. float distance = HYPOT(px - mx, py - my); - /** - * If doing the far_flag action, we want to be as far as possible - * from the starting point and from any other probed points. We - * want the next point spread out and filling in any blank spaces - * in the mesh. So we add in some of the distance to every probed - * point we can find. - */ - if (far_flag) { - for (uint8_t k = 0; k < GRID_MAX_POINTS_X; k++) { - for (uint8_t l = 0; l < GRID_MAX_POINTS_Y; l++) { - if (i != k && j != l && !isnan(z_values[k][l])) { - //distance += pow((float) abs(i - k) * (MESH_X_DIST), 2) + pow((float) abs(j - l) * (MESH_Y_DIST), 2); // working here - distance += HYPOT(MESH_X_DIST, MESH_Y_DIST) / log(HYPOT((i - k) * (MESH_X_DIST) + .001, (j - l) * (MESH_Y_DIST)) + .001); - } - } - } - } - else // factor in the distance from the current location for the normal case // so the nozzle isn't running all over the bed. - distance += HYPOT(raw_x - mx, raw_y - my) * 0.1; - - // if far_flag, look for farthest point - if (far_flag == (distance > best_so_far) && distance != best_so_far) { - best_so_far = distance; // We found a closer/farther location with + distance += HYPOT(current_position[X_AXIS] - mx, current_position[Y_AXIS] - my) * 0.1; + if (distance < best_so_far) { + best_so_far = distance; // We found a closer location with out_mesh.x_index = i; // the specified type of mesh value. out_mesh.y_index = j; out_mesh.distance = best_so_far; @@ -1474,7 +1474,13 @@ #if ENABLED(NEWPANEL) - void unified_bed_leveling::fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map) { + void abort_fine_tune() { + lcd_return_to_status(); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + LCD_MESSAGEPGM(MSG_EDITING_STOPPED); + } + + void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) { if (!parser.seen('R')) // fine_tune_mesh() is special. If no repetition count flag is specified g29_repetition_cnt = 1; // do exactly one mesh location. Otherwise use what the parser decided. @@ -1489,7 +1495,7 @@ mesh_index_pair location; - if (!position_is_reachable_xy(lx, ly)) { + if (!position_is_reachable(rx, ry)) { SERIAL_PROTOCOLLNPGM("(X,Y) outside printable radius."); return; } @@ -1498,75 +1504,59 @@ LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(lx, ly); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); uint16_t not_done[16]; memset(not_done, 0xFF, sizeof(not_done)); do { - location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done, false); + location = find_closest_mesh_point_of_type(SET_IN_BITMAP, rx, ry, USE_NOZZLE_AS_REFERENCE, not_done); if (location.x_index < 0) break; // stop when we can't find any more reachable points. - bit_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a - // different location the next time through the loop + bitmap_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a + // different location the next time through the loop const float rawx = mesh_index_to_xpos(location.x_index), rawy = mesh_index_to_ypos(location.y_index); - if (!position_is_reachable_raw_xy(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable + if (!position_is_reachable(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable break; - float new_z = z_values[location.x_index][location.y_index]; - - if (isnan(new_z)) // if the mesh point is invalid, set it to 0.0 so it can be edited - new_z = 0.0; - - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to where we are going to edit - do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy)); - - new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place + do_blocking_move_to(rawx, rawy, Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to the edit point KEEPALIVE_STATE(PAUSED_FOR_USER); - has_control_of_lcd_panel = true; + lcd_external_control = true; if (do_ubl_mesh_map) display_map(g29_map_type); // show the user which point is being adjusted lcd_refresh(); + float new_z = z_values[location.x_index][location.y_index]; + if (isnan(new_z)) new_z = 0.0; // Set invalid mesh points to 0.0 so they can be edited + new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place + lcd_mesh_edit_setup(new_z); - do { + while (!is_lcd_clicked()) { new_z = lcd_mesh_edit(); #if ENABLED(UBL_MESH_EDIT_MOVES_Z) do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited #endif idle(); - } while (!ubl_lcd_clicked()); + } - if (!ubl_lcd_map_control) lcd_return_to_status(); + if (!lcd_map_control) lcd_return_to_status(); // The technique used here generates a race condition for the encoder click. // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) or here. // Let's work on specifying a proper API for the LCD ASAP, OK? - has_control_of_lcd_panel = true; + lcd_external_control = true; - // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is + // this sequence to detect an is_lcd_clicked() debounce it and leave if it is // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This // should be redone and compressed. - const millis_t nxt = millis() + 1500UL; - while (ubl_lcd_clicked()) { // debounce and watch for abort - idle(); - if (ELAPSED(millis(), nxt)) { - lcd_return_to_status(); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - LCD_MESSAGEPGM(MSG_EDITING_STOPPED); - - while (ubl_lcd_clicked()) idle(); - - goto FINE_TUNE_EXIT; - } - } + if (click_and_hold(abort_fine_tune)) + goto FINE_TUNE_EXIT; safe_delay(20); // We don't want any switch noise. @@ -1578,19 +1568,18 @@ FINE_TUNE_EXIT: - has_control_of_lcd_panel = false; + lcd_external_control = false; KEEPALIVE_STATE(IN_HANDLER); if (do_ubl_mesh_map) display_map(g29_map_type); restore_ubl_active_state_and_leave(); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(lx, ly); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH); SERIAL_ECHOLNPGM("Done Editing Mesh"); - if (ubl_lcd_map_control) + if (lcd_map_control) lcd_goto_screen(_lcd_ubl_output_map_lcd); else lcd_return_to_status(); @@ -1628,16 +1617,10 @@ info3 PROGMEM = { GRID_MAX_POINTS_X - 1, 0, 0, GRID_MAX_POINTS_Y, true }; // Right side of the mesh looking left static const smart_fill_info * const info[] PROGMEM = { &info0, &info1, &info2, &info3 }; - // static const smart_fill_info info[] PROGMEM = { - // { 0, GRID_MAX_POINTS_X, 0, GRID_MAX_POINTS_Y - 2, false } PROGMEM, // Bottom of the mesh looking up - // { 0, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - 1, 0, false } PROGMEM, // Top of the mesh looking down - // { 0, GRID_MAX_POINTS_X - 2, 0, GRID_MAX_POINTS_Y, true } PROGMEM, // Left side of the mesh looking right - // { GRID_MAX_POINTS_X - 1, 0, 0, GRID_MAX_POINTS_Y, true } PROGMEM // Right side of the mesh looking left - // }; for (uint8_t i = 0; i < COUNT(info); ++i) { - const smart_fill_info *f = (smart_fill_info*)pgm_read_word(&info[i]); - const int8_t sx = pgm_read_word(&f->sx), sy = pgm_read_word(&f->sy), - ex = pgm_read_word(&f->ex), ey = pgm_read_word(&f->ey); + const smart_fill_info *f = (smart_fill_info*)pgm_read_ptr(&info[i]); + const int8_t sx = pgm_read_byte(&f->sx), sy = pgm_read_byte(&f->sy), + ex = pgm_read_byte(&f->ex), ey = pgm_read_byte(&f->ey); if (pgm_read_byte(&f->yfirst)) { const int8_t dir = ex > sx ? 1 : -1; for (uint8_t y = sy; y != ey; ++y) @@ -1656,10 +1639,10 @@ #if HAS_BED_PROBE void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map) { - constexpr int16_t x_min = max(MIN_PROBE_X, UBL_MESH_MIN_X), - x_max = min(MAX_PROBE_X, UBL_MESH_MAX_X), - y_min = max(MIN_PROBE_Y, UBL_MESH_MIN_Y), - y_max = min(MAX_PROBE_Y, UBL_MESH_MAX_Y); + constexpr int16_t x_min = max(MIN_PROBE_X, MESH_MIN_X), + x_max = min(MAX_PROBE_X, MESH_MAX_X), + y_min = max(MIN_PROBE_Y, MESH_MIN_Y), + y_max = min(MAX_PROBE_Y, MESH_MAX_Y); const float dx = float(x_max - x_min) / (g29_grid_size - 1.0), dy = float(y_max - y_min) / (g29_grid_size - 1.0); @@ -1669,29 +1652,29 @@ bool zig_zag = false; for (uint8_t ix = 0; ix < g29_grid_size; ix++) { - const float x = float(x_min) + ix * dx; + const float rx = float(x_min) + ix * dx; for (int8_t iy = 0; iy < g29_grid_size; iy++) { - const float y = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy); - float measured_z = probe_pt(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), parser.seen('E'), g29_verbose_level); // TODO: Needs error handling + const float ry = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy); + float measured_z = probe_pt(rx, ry, parser.seen('E'), g29_verbose_level); // TODO: Needs error handling #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { SERIAL_CHAR('('); - SERIAL_PROTOCOL_F(x, 7); + SERIAL_PROTOCOL_F(rx, 7); SERIAL_CHAR(','); - SERIAL_PROTOCOL_F(y, 7); + SERIAL_PROTOCOL_F(ry, 7); SERIAL_ECHOPGM(") logical: "); SERIAL_CHAR('('); - SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(x), 7); + SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(rx), 7); SERIAL_CHAR(','); - SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(y), 7); + SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(ry), 7); SERIAL_ECHOPGM(") measured: "); SERIAL_PROTOCOL_F(measured_z, 7); SERIAL_ECHOPGM(" correction: "); - SERIAL_PROTOCOL_F(get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)), 7); + SERIAL_PROTOCOL_F(get_z_correction(rx, ry), 7); } #endif - measured_z -= get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)) /* + zprobe_zoffset */ ; + measured_z -= get_z_correction(rx, ry) /* + zprobe_zoffset */ ; #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { @@ -1701,7 +1684,7 @@ } #endif - incremental_LSF(&lsf_results, x, y, measured_z); + incremental_LSF(&lsf_results, rx, ry, measured_z); } zig_zag ^= true; diff --git a/Marlin/ubl_motion.cpp b/Marlin/ubl_motion.cpp index b9f85301ef..07a8b1a86e 100644 --- a/Marlin/ubl_motion.cpp +++ b/Marlin/ubl_motion.cpp @@ -30,249 +30,93 @@ #include #include - extern float destination[XYZE]; - #if AVR_AT90USB1286_FAMILY // Teensyduino & Printrboard IDE extensions have compile errors without this - inline void set_current_to_destination() { COPY(current_position, destination); } + inline void set_current_from_destination() { COPY(current_position, destination); } #else - extern void set_current_to_destination(); + extern void set_current_from_destination(); #endif -#if ENABLED(DELTA) + #if !UBL_SEGMENTED - extern float delta[ABC], - endstop_adj[ABC]; - - extern float delta_radius, - delta_tower_angle_trim[ABC], - delta_tower[ABC][2], - delta_diagonal_rod, - delta_calibration_radius, - delta_diagonal_rod_2_tower[ABC], - delta_segments_per_second, - delta_clip_start_height; - - extern float delta_safe_distance_from_top(); - -#endif - - - static void debug_echo_axis(const AxisEnum axis) { - if (current_position[axis] == destination[axis]) - SERIAL_ECHOPGM("-------------"); - else - SERIAL_ECHO_F(destination[X_AXIS], 6); - } - - void debug_current_and_destination(const char *title) { - - // if the title message starts with a '!' it is so important, we are going to - // ignore the status of the g26_debug_flag - if (*title != '!' && !ubl.g26_debug_flag) return; - - const float de = destination[E_AXIS] - current_position[E_AXIS]; - - if (de == 0.0) return; // Printing moves only - - const float dx = destination[X_AXIS] - current_position[X_AXIS], - dy = destination[Y_AXIS] - current_position[Y_AXIS], - xy_dist = HYPOT(dx, dy); - - if (xy_dist == 0.0) return; - - SERIAL_ECHOPGM(" fpmm="); - const float fpmm = de / xy_dist; - SERIAL_ECHO_F(fpmm, 6); - - SERIAL_ECHOPGM(" current=( "); - SERIAL_ECHO_F(current_position[X_AXIS], 6); - SERIAL_ECHOPGM(", "); - SERIAL_ECHO_F(current_position[Y_AXIS], 6); - SERIAL_ECHOPGM(", "); - SERIAL_ECHO_F(current_position[Z_AXIS], 6); - SERIAL_ECHOPGM(", "); - SERIAL_ECHO_F(current_position[E_AXIS], 6); - SERIAL_ECHOPGM(" ) destination=( "); - debug_echo_axis(X_AXIS); - SERIAL_ECHOPGM(", "); - debug_echo_axis(Y_AXIS); - SERIAL_ECHOPGM(", "); - debug_echo_axis(Z_AXIS); - SERIAL_ECHOPGM(", "); - debug_echo_axis(E_AXIS); - SERIAL_ECHOPGM(" ) "); - SERIAL_ECHO(title); - SERIAL_EOL(); - - } - - void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) { - /** - * Much of the nozzle movement will be within the same cell. So we will do as little computation - * as possible to determine if this is the case. If this move is within the same cell, we will - * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave - */ - const float start[XYZE] = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }, - end[XYZE] = { - destination[X_AXIS], - destination[Y_AXIS], - destination[Z_AXIS], - destination[E_AXIS] - }; - - const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])), - cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])), - cell_dest_xi = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])), - cell_dest_yi = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS])); - - if (g26_debug_flag) { - SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]); - SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]); - SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]); - SERIAL_ECHOPAIR(", ee=", end[E_AXIS]); - SERIAL_CHAR(')'); - SERIAL_EOL(); - debug_current_and_destination(PSTR("Start of ubl.line_to_destination()")); - } - - if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell, + void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, const uint8_t extruder) { /** - * we don't need to break up the move - * - * If we are moving off the print bed, we are going to allow the move at this level. - * But we detect it and isolate it. For now, we just pass along the request. + * Much of the nozzle movement will be within the same cell. So we will do as little computation + * as possible to determine if this is the case. If this move is within the same cell, we will + * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave */ + #if ENABLED(SKEW_CORRECTION) + // For skew correction just adjust the destination point and we're done + float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] }, + end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] }; + planner.skew(start[X_AXIS], start[Y_AXIS], start[Z_AXIS]); + planner.skew(end[X_AXIS], end[Y_AXIS], end[Z_AXIS]); + #else + const float (&start)[XYZE] = current_position, + (&end)[XYZE] = destination; + #endif - if (!WITHIN(cell_dest_xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(cell_dest_yi, 0, GRID_MAX_POINTS_Y - 1)) { + const int cell_start_xi = get_cell_index_x(start[X_AXIS]), + cell_start_yi = get_cell_index_y(start[Y_AXIS]), + cell_dest_xi = get_cell_index_x(end[X_AXIS]), + cell_dest_yi = get_cell_index_y(end[Y_AXIS]); - // Note: There is no Z Correction in this case. We are off the grid and don't know what - // a reasonable correction would be. - - planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + state.z_offset, end[E_AXIS], feed_rate, extruder); - set_current_to_destination(); - - if (g26_debug_flag) - debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination()")); - - return; + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" ubl.line_to_destination_cartesian(xe=", destination[X_AXIS]); + SERIAL_ECHOPAIR(", ye=", destination[Y_AXIS]); + SERIAL_ECHOPAIR(", ze=", destination[Z_AXIS]); + SERIAL_ECHOPAIR(", ee=", destination[E_AXIS]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + debug_current_and_destination(PSTR("Start of ubl.line_to_destination_cartesian()")); } - FINAL_MOVE: + if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell, + /** + * we don't need to break up the move + * + * If we are moving off the print bed, we are going to allow the move at this level. + * But we detect it and isolate it. For now, we just pass along the request. + */ - /** - * Optimize some floating point operations here. We could call float get_z_correction(float x0, float y0) to - * generate the correction for us. But we can lighten the load on the CPU by doing a modified version of the function. - * We are going to only calculate the amount we are from the first mesh line towards the second mesh line once. - * We will use this fraction in both of the original two Z Height calculations for the bi-linear interpolation. And, - * instead of doing a generic divide of the distance, we know the distance is MESH_X_DIST so we can use the preprocessor - * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide. - */ + if (!WITHIN(cell_dest_xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(cell_dest_yi, 0, GRID_MAX_POINTS_Y - 1)) { - const float xratio = (RAW_X_POSITION(end[X_AXIS]) - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST)); + // Note: There is no Z Correction in this case. We are off the grid and don't know what + // a reasonable correction would be. - float z1 = z_values[cell_dest_xi ][cell_dest_yi ] + xratio * - (z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]), - z2 = z_values[cell_dest_xi ][cell_dest_yi + 1] + xratio * - (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]); + planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS], end[E_AXIS], feed_rate, extruder); + set_current_from_destination(); - if (cell_dest_xi >= GRID_MAX_POINTS_X - 1) z1 = z2 = 0.0; + if (g26_debug_flag) + debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination_cartesian()")); - // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we - // are going to apply the Y-Distance into the cell to interpolate the final Z correction. + return; + } - const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST)); - float z0 = cell_dest_yi < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * fade_scaling_factor_for_z(end[Z_AXIS]) : 0.0; - - /** - * If part of the Mesh is undefined, it will show up as NAN - * in z_values[][] and propagate through the - * calculations. If our correction is NAN, we throw it out - * because part of the Mesh is undefined and we don't have the - * information we need to complete the height correction. - */ - if (isnan(z0)) z0 = 0.0; - - planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + state.z_offset, end[E_AXIS], feed_rate, extruder); - - if (g26_debug_flag) - debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination()")); - - set_current_to_destination(); - return; - } - - /** - * If we get here, we are processing a move that crosses at least one Mesh Line. We will check - * for the simple case of just crossing X or just crossing Y Mesh Lines after we get all the details - * of the move figured out. We can process the easy case of just crossing an X or Y Mesh Line with less - * computation and in fact most lines are of this nature. We will check for that in the following - * blocks of code: - */ - - const float dx = end[X_AXIS] - start[X_AXIS], - dy = end[Y_AXIS] - start[Y_AXIS]; - - const int left_flag = dx < 0.0 ? 1 : 0, - down_flag = dy < 0.0 ? 1 : 0; - - const float adx = left_flag ? -dx : dx, - ady = down_flag ? -dy : dy; - - const int dxi = cell_start_xi == cell_dest_xi ? 0 : left_flag ? -1 : 1, - dyi = cell_start_yi == cell_dest_yi ? 0 : down_flag ? -1 : 1; - - /** - * Compute the scaling factor for the extruder for each partial move. - * We need to watch out for zero length moves because it will cause us to - * have an infinate scaling factor. We are stuck doing a floating point - * divide to get our scaling factor, but after that, we just multiply by this - * number. We also pick our scaling factor based on whether the X or Y - * component is larger. We use the biggest of the two to preserve precision. - */ - - const bool use_x_dist = adx > ady; - - float on_axis_distance = use_x_dist ? dx : dy, - e_position = end[E_AXIS] - start[E_AXIS], - z_position = end[Z_AXIS] - start[Z_AXIS]; - - const float e_normalized_dist = e_position / on_axis_distance, - z_normalized_dist = z_position / on_axis_distance; - - int current_xi = cell_start_xi, - current_yi = cell_start_yi; - - const float m = dy / dx, - c = start[Y_AXIS] - m * start[X_AXIS]; - - const bool inf_normalized_flag = (isinf(e_normalized_dist) != 0), - inf_m_flag = (isinf(m) != 0); - /** - * This block handles vertical lines. These are lines that stay within the same - * X Cell column. They do not need to be perfectly vertical. They just can - * not cross into another X Cell column. - */ - if (dxi == 0) { // Check for a vertical line - current_yi += down_flag; // Line is heading down, we just want to go to the bottom - while (current_yi != cell_dest_yi + down_flag) { - current_yi += dyi; - const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi)); + FINAL_MOVE: /** - * if the slope of the line is infinite, we won't do the calculations - * else, we know the next X is the same so we can recover and continue! - * Calculate X at the next Y mesh line + * Optimize some floating point operations here. We could call float get_z_correction(float x0, float y0) to + * generate the correction for us. But we can lighten the load on the CPU by doing a modified version of the function. + * We are going to only calculate the amount we are from the first mesh line towards the second mesh line once. + * We will use this fraction in both of the original two Z Height calculations for the bi-linear interpolation. And, + * instead of doing a generic divide of the distance, we know the distance is MESH_X_DIST so we can use the preprocessor + * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide. */ - const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m; - float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi); + const float xratio = (end[X_AXIS] - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST)); - z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); + float z1 = z_values[cell_dest_xi ][cell_dest_yi ] + xratio * + (z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]), + z2 = z_values[cell_dest_xi ][cell_dest_yi + 1] + xratio * + (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]); + + if (cell_dest_xi >= GRID_MAX_POINTS_X - 1) z1 = z2 = 0.0; + + // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we + // are going to apply the Y-Distance into the cell to interpolate the final Z correction. + + const float yratio = (end[Y_AXIS] - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST)); + float z0 = cell_dest_yi < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * planner.fade_scaling_factor_for_z(end[Z_AXIS]) : 0.0; /** * If part of the Mesh is undefined, it will show up as NAN @@ -283,17 +127,256 @@ */ if (isnan(z0)) z0 = 0.0; - const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi)); + planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0, end[E_AXIS], feed_rate, extruder); + + if (g26_debug_flag) + debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination_cartesian()")); + + set_current_from_destination(); + return; + } + + /** + * If we get here, we are processing a move that crosses at least one Mesh Line. We will check + * for the simple case of just crossing X or just crossing Y Mesh Lines after we get all the details + * of the move figured out. We can process the easy case of just crossing an X or Y Mesh Line with less + * computation and in fact most lines are of this nature. We will check for that in the following + * blocks of code: + */ + + const float dx = end[X_AXIS] - start[X_AXIS], + dy = end[Y_AXIS] - start[Y_AXIS]; + + const int left_flag = dx < 0.0 ? 1 : 0, + down_flag = dy < 0.0 ? 1 : 0; + + const float adx = left_flag ? -dx : dx, + ady = down_flag ? -dy : dy; + + const int dxi = cell_start_xi == cell_dest_xi ? 0 : left_flag ? -1 : 1, + dyi = cell_start_yi == cell_dest_yi ? 0 : down_flag ? -1 : 1; + + /** + * Compute the scaling factor for the extruder for each partial move. + * We need to watch out for zero length moves because it will cause us to + * have an infinate scaling factor. We are stuck doing a floating point + * divide to get our scaling factor, but after that, we just multiply by this + * number. We also pick our scaling factor based on whether the X or Y + * component is larger. We use the biggest of the two to preserve precision. + */ + + const bool use_x_dist = adx > ady; + + float on_axis_distance = use_x_dist ? dx : dy, + e_position = end[E_AXIS] - start[E_AXIS], + z_position = end[Z_AXIS] - start[Z_AXIS]; + + const float e_normalized_dist = e_position / on_axis_distance, + z_normalized_dist = z_position / on_axis_distance; + + int current_xi = cell_start_xi, + current_yi = cell_start_yi; + + const float m = dy / dx, + c = start[Y_AXIS] - m * start[X_AXIS]; + + const bool inf_normalized_flag = (isinf(e_normalized_dist) != 0), + inf_m_flag = (isinf(m) != 0); + /** + * This block handles vertical lines. These are lines that stay within the same + * X Cell column. They do not need to be perfectly vertical. They just can + * not cross into another X Cell column. + */ + if (dxi == 0) { // Check for a vertical line + current_yi += down_flag; // Line is heading down, we just want to go to the bottom + while (current_yi != cell_dest_yi + down_flag) { + current_yi += dyi; + const float next_mesh_line_y = mesh_index_to_ypos(current_yi); + + /** + * if the slope of the line is infinite, we won't do the calculations + * else, we know the next X is the same so we can recover and continue! + * Calculate X at the next Y mesh line + */ + const float rx = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m; + + float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi, current_yi) + * planner.fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + const float ry = mesh_index_to_ypos(current_yi); + + /** + * Without this check, it is possible for the algorithm to generate a zero length move in the case + * where the line is heading down and it is starting right on a Mesh Line boundary. For how often that + * happens, it might be best to remove the check and always 'schedule' the move because + * the planner.buffer_segment() routine will filter it if that happens. + */ + if (ry != start[Y_AXIS]) { + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + + planner.buffer_segment(rx, ry, z_position + z0, e_position, feed_rate, extruder); + } //else printf("FIRST MOVE PRUNED "); + } + + if (g26_debug_flag) + debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination_cartesian()")); + + // + // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done. + // + if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) + goto FINAL_MOVE; + + set_current_from_destination(); + return; + } + + /** + * + * This block handles horizontal lines. These are lines that stay within the same + * Y Cell row. They do not need to be perfectly horizontal. They just can + * not cross into another Y Cell row. + * + */ + + if (dyi == 0) { // Check for a horizontal line + current_xi += left_flag; // Line is heading left, we just want to go to the left + // edge of this cell for the first move. + while (current_xi != cell_dest_xi + left_flag) { + current_xi += dxi; + const float next_mesh_line_x = mesh_index_to_xpos(current_xi), + ry = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line + + float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi, current_yi) + * planner.fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + const float rx = mesh_index_to_xpos(current_xi); + + /** + * Without this check, it is possible for the algorithm to generate a zero length move in the case + * where the line is heading left and it is starting right on a Mesh Line boundary. For how often + * that happens, it might be best to remove the check and always 'schedule' the move because + * the planner.buffer_segment() routine will filter it if that happens. + */ + if (rx != start[X_AXIS]) { + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + + planner.buffer_segment(rx, ry, z_position + z0, e_position, feed_rate, extruder); + } //else printf("FIRST MOVE PRUNED "); + } + + if (g26_debug_flag) + debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination_cartesian()")); + + if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) + goto FINAL_MOVE; + + set_current_from_destination(); + return; + } + + /** + * + * This block handles the generic case of a line crossing both X and Y Mesh lines. + * + */ + + int xi_cnt = cell_start_xi - cell_dest_xi, + yi_cnt = cell_start_yi - cell_dest_yi; + + if (xi_cnt < 0) xi_cnt = -xi_cnt; + if (yi_cnt < 0) yi_cnt = -yi_cnt; + + current_xi += left_flag; + current_yi += down_flag; + + while (xi_cnt > 0 || yi_cnt > 0) { + + const float next_mesh_line_x = mesh_index_to_xpos(current_xi + dxi), + next_mesh_line_y = mesh_index_to_ypos(current_yi + dyi), + ry = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line + rx = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line + // (No need to worry about m being zero. + // If that was the case, it was already detected + // as a vertical line move above.) + + if (left_flag == (rx > next_mesh_line_x)) { // Check if we hit the Y line first + // Yes! Crossing a Y Mesh Line next + float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi - left_flag, current_yi + dyi) + * planner.fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; - /** - * Without this check, it is possible for the algorithm to generate a zero length move in the case - * where the line is heading down and it is starting right on a Mesh Line boundary. For how often that - * happens, it might be best to remove the check and always 'schedule' the move because - * the planner._buffer_line() routine will filter it if that happens. - */ - if (y != start[Y_AXIS]) { if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS]; + on_axis_distance = use_x_dist ? rx - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, feed_rate, extruder); + current_yi += dyi; + yi_cnt--; + } + else { + // Yes! Crossing a X Mesh Line next + float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi + dxi, current_yi - down_flag) + * planner.fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : ry - start[Y_AXIS]; e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; } @@ -302,223 +385,49 @@ z_position = end[Z_AXIS]; } - planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); - } //else printf("FIRST MOVE PRUNED "); + planner.buffer_segment(next_mesh_line_x, ry, z_position + z0, e_position, feed_rate, extruder); + current_xi += dxi; + xi_cnt--; + } + + if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE } if (g26_debug_flag) - debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination()")); - - // - // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done. - // - if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) - goto FINAL_MOVE; - - set_current_to_destination(); - return; - } - - /** - * - * This block handles horizontal lines. These are lines that stay within the same - * Y Cell row. They do not need to be perfectly horizontal. They just can - * not cross into another Y Cell row. - * - */ - - if (dyi == 0) { // Check for a horizontal line - current_xi += left_flag; // Line is heading left, we just want to go to the left - // edge of this cell for the first move. - while (current_xi != cell_dest_xi + left_flag) { - current_xi += dxi; - const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)), - y = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line - - float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi); - - z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); - - /** - * If part of the Mesh is undefined, it will show up as NAN - * in z_values[][] and propagate through the - * calculations. If our correction is NAN, we throw it out - * because part of the Mesh is undefined and we don't have the - * information we need to complete the height correction. - */ - if (isnan(z0)) z0 = 0.0; - - const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)); - - /** - * Without this check, it is possible for the algorithm to generate a zero length move in the case - * where the line is heading left and it is starting right on a Mesh Line boundary. For how often - * that happens, it might be best to remove the check and always 'schedule' the move because - * the planner._buffer_line() routine will filter it if that happens. - */ - if (x != start[X_AXIS]) { - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS]; - e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move - z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; - } - else { - e_position = end[E_AXIS]; - z_position = end[Z_AXIS]; - } - - planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); - } //else printf("FIRST MOVE PRUNED "); - } - - if (g26_debug_flag) - debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination()")); + debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination_cartesian()")); if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) goto FINAL_MOVE; - set_current_to_destination(); - return; + set_current_from_destination(); } - /** - * - * This block handles the generic case of a line crossing both X and Y Mesh lines. - * - */ - - int xi_cnt = cell_start_xi - cell_dest_xi, - yi_cnt = cell_start_yi - cell_dest_yi; - - if (xi_cnt < 0) xi_cnt = -xi_cnt; - if (yi_cnt < 0) yi_cnt = -yi_cnt; - - current_xi += left_flag; - current_yi += down_flag; - - while (xi_cnt > 0 || yi_cnt > 0) { - - const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)), - next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)), - y = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line - x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line - // (No need to worry about m being zero. - // If that was the case, it was already detected - // as a vertical line move above.) - - if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first - // Yes! Crossing a Y Mesh Line next - float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi); - - z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); - - /** - * If part of the Mesh is undefined, it will show up as NAN - * in z_values[][] and propagate through the - * calculations. If our correction is NAN, we throw it out - * because part of the Mesh is undefined and we don't have the - * information we need to complete the height correction. - */ - if (isnan(z0)) z0 = 0.0; - - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? x - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS]; - e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; - z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; - } - else { - e_position = end[E_AXIS]; - z_position = end[Z_AXIS]; - } - planner._buffer_line(x, next_mesh_line_y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); - current_yi += dyi; - yi_cnt--; - } - else { - // Yes! Crossing a X Mesh Line next - float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag); - - z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); - - /** - * If part of the Mesh is undefined, it will show up as NAN - * in z_values[][] and propagate through the - * calculations. If our correction is NAN, we throw it out - * because part of the Mesh is undefined and we don't have the - * information we need to complete the height correction. - */ - if (isnan(z0)) z0 = 0.0; - - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : y - start[Y_AXIS]; - e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; - z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; - } - else { - e_position = end[E_AXIS]; - z_position = end[Z_AXIS]; - } - - planner._buffer_line(next_mesh_line_x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); - current_xi += dxi; - xi_cnt--; - } - - if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE - } - - if (g26_debug_flag) - debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination()")); - - if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) - goto FINAL_MOVE; - - set_current_to_destination(); - } - - #if UBL_DELTA - - // macro to inline copy exactly 4 floats, don't rely on sizeof operator - #define COPY_XYZE( target, source ) { \ - target[X_AXIS] = source[X_AXIS]; \ - target[Y_AXIS] = source[Y_AXIS]; \ - target[Z_AXIS] = source[Z_AXIS]; \ - target[E_AXIS] = source[E_AXIS]; \ - } + #else // UBL_SEGMENTED #if IS_SCARA // scale the feed rate from mm/s to degrees/s static float scara_feed_factor, scara_oldA, scara_oldB; #endif // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic, - // so we call _buffer_line directly here. Per-segmented leveling and kinematics performed first. + // so we call buffer_segment directly here. Per-segmented leveling and kinematics performed first. - inline void _O2 ubl_buffer_segment_raw( float rx, float ry, float rz, float le, float fr ) { + inline void _O2 ubl_buffer_segment_raw(const float (&in_raw)[XYZE], const float &fr) { + + #if ENABLED(SKEW_CORRECTION) + float raw[XYZE] = { in_raw[X_AXIS], in_raw[Y_AXIS], in_raw[Z_AXIS], in_raw[E_AXIS] }; + planner.skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); + #else + const float (&raw)[XYZE] = in_raw; + #endif #if ENABLED(DELTA) // apply delta inverse_kinematics - const float delta_A = rz + SQRT( delta_diagonal_rod_2_tower[A_AXIS] - - HYPOT2( delta_tower[A_AXIS][X_AXIS] - rx, - delta_tower[A_AXIS][Y_AXIS] - ry )); - - const float delta_B = rz + SQRT( delta_diagonal_rod_2_tower[B_AXIS] - - HYPOT2( delta_tower[B_AXIS][X_AXIS] - rx, - delta_tower[B_AXIS][Y_AXIS] - ry )); - - const float delta_C = rz + SQRT( delta_diagonal_rod_2_tower[C_AXIS] - - HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx, - delta_tower[C_AXIS][Y_AXIS] - ry )); - - planner._buffer_line(delta_A, delta_B, delta_C, le, fr, active_extruder); + DELTA_RAW_IK(); + planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder); #elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw) - const float lseg[XYZ] = { LOGICAL_X_POSITION(rx), - LOGICAL_Y_POSITION(ry), - LOGICAL_Z_POSITION(rz) - }; - - inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ] + inverse_kinematics(raw); // this writes delta[ABC] from raw[XYZE] // should move the feedrate scaling to scara inverse_kinematics const float adiff = FABS(delta[A_AXIS] - scara_oldA), @@ -527,40 +436,46 @@ scara_oldB = delta[B_AXIS]; float s_feedrate = max(adiff, bdiff) * scara_feed_factor; - planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], le, s_feedrate, active_extruder); + planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder); #else // CARTESIAN - // Cartesian _buffer_line seems to take LOGICAL, not RAW coordinates - - const float lx = LOGICAL_X_POSITION(rx), - ly = LOGICAL_Y_POSITION(ry), - lz = LOGICAL_Z_POSITION(rz); - - planner._buffer_line(lx, ly, lz, le, fr, active_extruder); + planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder); #endif - } + #if IS_SCARA + #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm + #elif ENABLED(DELTA) + #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) + #else // CARTESIAN + #ifdef LEVELED_SEGMENT_LENGTH + #define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH + #else + #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation) + #endif + #endif /** * Prepare a segmented linear move for DELTA/SCARA/CARTESIAN with UBL and FADE semantics. - * This calls planner._buffer_line multiple times for small incremental moves. + * This calls planner.buffer_segment multiple times for small incremental moves. * Returns true if did NOT move, false if moved (requires current_position update). */ - bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate) { + bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float (&rtarget)[XYZE], const float &feedrate) { - if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) // fail if moving outside reachable boundary + if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS])) // fail if moving outside reachable boundary return true; // did not move, so current_position still accurate - const float tot_dx = ltarget[X_AXIS] - current_position[X_AXIS], - tot_dy = ltarget[Y_AXIS] - current_position[Y_AXIS], - tot_dz = ltarget[Z_AXIS] - current_position[Z_AXIS], - tot_de = ltarget[E_AXIS] - current_position[E_AXIS]; + const float total[XYZE] = { + rtarget[X_AXIS] - current_position[X_AXIS], + rtarget[Y_AXIS] - current_position[Y_AXIS], + rtarget[Z_AXIS] - current_position[Z_AXIS], + rtarget[E_AXIS] - current_position[E_AXIS] + }; - const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy); // total horizontal xy distance + const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]); // total horizontal xy distance #if IS_KINEMATIC const float seconds = cartesian_xy_mm / feedrate; // seconds to move xy distance at requested rate @@ -580,65 +495,41 @@ scara_oldB = stepper.get_axis_position_degrees(B_AXIS); #endif - const float seg_dx = tot_dx * inv_segments, - seg_dy = tot_dy * inv_segments, - seg_dz = tot_dz * inv_segments, - seg_de = tot_de * inv_segments; + const float diff[XYZE] = { + total[X_AXIS] * inv_segments, + total[Y_AXIS] * inv_segments, + total[Z_AXIS] * inv_segments, + total[E_AXIS] * inv_segments + }; // Note that E segment distance could vary slightly as z mesh height // changes for each segment, but small enough to ignore. - float seg_rx = RAW_X_POSITION(current_position[X_AXIS]), - seg_ry = RAW_Y_POSITION(current_position[Y_AXIS]), - seg_rz = RAW_Z_POSITION(current_position[Z_AXIS]), - seg_le = current_position[E_AXIS]; - - const bool above_fade_height = ( - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - planner.z_fade_height != 0 && planner.z_fade_height < RAW_Z_POSITION(ltarget[Z_AXIS]) - #else - false - #endif - ); + float raw[XYZE] = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; // Only compute leveling per segment if ubl active and target below z_fade_height. - - if (!state.active || above_fade_height) { // no mesh leveling - - const float z_offset = state.active ? state.z_offset : 0.0; - - do { - - if (--segments) { // not the last segment - seg_rx += seg_dx; - seg_ry += seg_dy; - seg_rz += seg_dz; - seg_le += seg_de; - } else { // last segment, use exact destination - seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); - seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); - seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); - seg_le = ltarget[E_AXIS]; - } - - ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz + z_offset, seg_le, feedrate ); - - } while (segments); - - return false; // moved but did not set_current_to_destination(); + if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) { // no mesh leveling + while (--segments) { + LOOP_XYZE(i) raw[i] += diff[i]; + ubl_buffer_segment_raw(raw, feedrate); + } + ubl_buffer_segment_raw(rtarget, feedrate); + return false; // moved but did not set_current_from_destination(); } // Otherwise perform per-segment leveling #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - const float fade_scaling_factor = fade_scaling_factor_for_z(ltarget[Z_AXIS]); + const float fade_scaling_factor = planner.fade_scaling_factor_for_z(rtarget[Z_AXIS]); #endif // increment to first segment destination - seg_rx += seg_dx; - seg_ry += seg_dy; - seg_rz += seg_dz; - seg_le += seg_de; + LOOP_XYZE(i) raw[i] += diff[i]; for(;;) { // for each mesh cell encountered during the move @@ -649,8 +540,8 @@ // in top of loop and again re-find same adjacent cell and use it, just less efficient // for mesh inset area. - int8_t cell_xi = (seg_rx - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST)), - cell_yi = (seg_ry - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_X_DIST)); + int8_t cell_xi = (raw[X_AXIS] - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)), + cell_yi = (raw[Y_AXIS] - (MESH_MIN_Y)) * (1.0 / (MESH_X_DIST)); cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1); cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1); @@ -663,13 +554,13 @@ z_x0y1 = z_values[cell_xi ][cell_yi+1], // z at lower right corner z_x1y1 = z_values[cell_xi+1][cell_yi+1]; // z at upper right corner - if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating state.active (G29 A) + if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A) if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points if (isnan(z_x0y1)) z_x0y1 = 0; // in order to avoid isnan tests per cell, if (isnan(z_x1y1)) z_x1y1 = 0; // thus guessing zero for undefined points - float cx = seg_rx - x0, // cell-relative x and y - cy = seg_ry - y0; + float cx = raw[X_AXIS] - x0, // cell-relative x and y + cy = raw[Y_AXIS] - y0; const float z_xmy0 = (z_x1y0 - z_x0y0) * (1.0 / (MESH_X_DIST)), // z slope per x along y0 (lower left to lower right) z_xmy1 = (z_x1y1 - z_x0y1) * (1.0 / (MESH_X_DIST)); // z slope per x along y1 (upper left to upper right) @@ -687,42 +578,35 @@ // and the z_cxym slope will change, both as a function of cx within the cell, and // each change by a constant for fixed segment lengths. - const float z_sxy0 = z_xmy0 * seg_dx, // per-segment adjustment to z_cxy0 - z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * seg_dx; // per-segment adjustment to z_cxym + const float z_sxy0 = z_xmy0 * diff[X_AXIS], // per-segment adjustment to z_cxy0 + z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * diff[X_AXIS]; // per-segment adjustment to z_cxym for(;;) { // for all segments within this mesh cell - float z_cxcy = z_cxy0 + z_cxym * cy; // interpolated mesh z height along cx at cy + if (--segments == 0) // if this is last segment, use rtarget for exact + COPY(raw, rtarget); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - z_cxcy *= fade_scaling_factor; // apply fade factor to interpolated mesh height - #endif + const float z_cxcy = (z_cxy0 + z_cxym * cy) // interpolated mesh z height along cx at cy + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + * fade_scaling_factor // apply fade factor to interpolated mesh height + #endif + ; - z_cxcy += state.z_offset; // add fixed mesh offset from G29 Z + const float z = raw[Z_AXIS]; + raw[Z_AXIS] += z_cxcy; + ubl_buffer_segment_raw(raw, feedrate); + raw[Z_AXIS] = z; - if (--segments == 0) { // if this is last segment, use ltarget for exact - seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); - seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); - seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); - seg_le = ltarget[E_AXIS]; - } + if (segments == 0) // done with last segment + return false; // did not set_current_from_destination() - ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz + z_cxcy, seg_le, feedrate ); + LOOP_XYZE(i) raw[i] += diff[i]; - if (segments == 0 ) // done with last segment - return false; // did not set_current_to_destination() + cx += diff[X_AXIS]; + cy += diff[Y_AXIS]; - seg_rx += seg_dx; - seg_ry += seg_dy; - seg_rz += seg_dz; - seg_le += seg_de; - - cx += seg_dx; - cy += seg_dy; - - if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST)) { // done within this cell, break to next + if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST)) // done within this cell, break to next break; - } // Next segment still within same mesh cell, adjust the per-segment // slope and intercept to compute next z height. @@ -734,7 +618,6 @@ } // cell loop } - #endif // UBL_DELTA + #endif // UBL_SEGMENTED #endif // AUTO_BED_LEVELING_UBL - diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 83ce9d2fe4..8d78d5a503 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -33,6 +33,7 @@ #include "stepper.h" #include "configuration_store.h" #include "utility.h" +#include "gcode.h" #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) #include "buzzer.h" @@ -49,7 +50,14 @@ #if ENABLED(AUTO_BED_LEVELING_UBL) #include "ubl.h" - bool ubl_lcd_map_control = false; +#elif HAS_ABL + #include "planner.h" +#elif ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) + bool lcd_external_control; // = false #endif // Initialized by settings.load() @@ -68,13 +76,22 @@ int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_spe #endif #endif -uint8_t lcd_status_message_level; +uint8_t lcd_status_update_delay = 1, // First update one loop delayed + lcd_status_message_level; // Higher level blocks lower level char lcd_status_message[3 * (LCD_WIDTH) + 1] = WELCOME_MSG; // worst case is kana with up to 3*LCD_WIDTH+1 #if ENABLED(STATUS_MESSAGE_SCROLLING) uint8_t status_scroll_pos = 0; #endif +#if ENABLED(SCROLL_LONG_FILENAMES) + uint8_t filename_scroll_pos, filename_scroll_max, filename_scroll_hash; +#endif + +#if ENABLED(LCD_SET_PROGRESS_MANUALLY) + uint8_t progress_bar_percent; +#endif + #if ENABLED(DOGLCD) #include "ultralcd_impl_DOGM.h" #include @@ -167,6 +184,11 @@ uint16_t max_display_update_time = 0; void lcd_info_menu(); #endif // LCD_INFO_MENU + #if ENABLED(LED_CONTROL_MENU) + #include "leds.h" + void lcd_led_menu(); + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) void lcd_advanced_pause_toocold_menu(); void lcd_advanced_pause_option_menu(); @@ -190,15 +212,10 @@ uint16_t max_display_update_time = 0; void lcd_control_retract_menu(); #endif - #if ENABLED(DELTA_CALIBRATION_MENU) + #if ENABLED(DELTA_CALIBRATION_MENU) || ENABLED(DELTA_AUTO_CALIBRATION) void lcd_delta_calibrate_menu(); #endif - #if ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) - #include "mesh_bed_leveling.h" - extern void mesh_probing_done(); - #endif - //////////////////////////////////////////// //////////// Menu System Actions /////////// //////////////////////////////////////////// @@ -242,10 +259,6 @@ uint16_t max_display_update_time = 0; //////////// Menu System Macros //////////// //////////////////////////////////////////// - #ifndef ENCODER_FEEDRATE_DEADZONE - #define ENCODER_FEEDRATE_DEADZONE 6 - #endif - /** * MENU_ITEM generates draw & handler code for a menu item, potentially calling: * @@ -504,20 +517,22 @@ uint16_t max_display_update_time = 0; if (screen == lcd_status_screen) { defer_return_to_status = false; #if ENABLED(AUTO_BED_LEVELING_UBL) - ubl_lcd_map_control = false; + ubl.lcd_map_control = false; #endif screen_history_depth = 0; } lcd_implementation_clear(); // Re-initialize custom characters that may be re-used #if DISABLED(DOGLCD) && ENABLED(AUTO_BED_LEVELING_UBL) - if (!ubl_lcd_map_control) lcd_set_custom_characters( - #if ENABLED(LCD_PROGRESS_BAR) - screen == lcd_status_screen - #endif - ); + if (!ubl.lcd_map_control) { + lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + screen == lcd_status_screen ? CHARSET_INFO : CHARSET_MENU + #endif + ); + } #elif ENABLED(LCD_PROGRESS_BAR) - lcd_set_custom_characters(screen == lcd_status_screen); + lcd_set_custom_characters(screen == lcd_status_screen ? CHARSET_INFO : CHARSET_MENU); #endif lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; screen_changed = true; @@ -542,10 +557,9 @@ uint16_t max_display_update_time = 0; static bool no_reentry = false; if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, sync_message); if (no_reentry) return; - // Make this the current handler till all moves are done no_reentry = true; - screenFunc_t old_screen = currentScreen; + const screenFunc_t old_screen = currentScreen; lcd_goto_screen(_lcd_synchronize); stepper.synchronize(); no_reentry = false; @@ -603,36 +617,52 @@ void lcd_status_screen() { #endif #if ENABLED(LCD_PROGRESS_BAR) - millis_t ms = millis(); - #if DISABLED(PROGRESS_MSG_ONCE) - if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) { - progress_bar_ms = ms; - } + + // + // HD44780 implements the following message blinking and + // message expiration because Status Line and Progress Bar + // share the same line on the display. + // + + // Set current percentage from SD when actively printing + #if ENABLED(LCD_SET_PROGRESS_MANUALLY) + if (IS_SD_PRINTING) + progress_bar_percent = card.percentDone(); #endif + + millis_t ms = millis(); + + // If the message will blink rather than expire... + #if DISABLED(PROGRESS_MSG_ONCE) + if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) + progress_bar_ms = ms; + #endif + #if PROGRESS_MSG_EXPIRE > 0 + // Handle message expire if (expire_status_ms > 0) { - #if ENABLED(SDSUPPORT) - if (card.isFileOpen()) { - // Expire the message when printing is active - if (IS_SD_PRINTING) { - if (ELAPSED(ms, expire_status_ms)) { - lcd_status_message[0] = '\0'; - expire_status_ms = 0; - } - } - else { - expire_status_ms += LCD_UPDATE_INTERVAL; - } - } - else { + + #if DISABLED(LCD_SET_PROGRESS_MANUALLY) + const uint8_t progress_bar_percent = card.percentDone(); + #endif + + // Expire the message if a job is active and the bar has ticks + if (progress_bar_percent > 2 && !print_job_timer.isPaused()) { + if (ELAPSED(ms, expire_status_ms)) { + lcd_status_message[0] = '\0'; expire_status_ms = 0; } - #else - expire_status_ms = 0; - #endif // SDSUPPORT + } + else { + // Defer message expiration before bar appears + // and during any pause (not just SD) + expire_status_ms += LCD_UPDATE_INTERVAL; + } } - #endif + + #endif // PROGRESS_MSG_EXPIRE + #endif // LCD_PROGRESS_BAR #if ENABLED(ULTIPANEL) @@ -643,7 +673,7 @@ void lcd_status_screen() { #endif lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. #if ENABLED(LCD_PROGRESS_BAR) - false + CHARSET_MENU #endif ); lcd_goto_screen(lcd_main_menu); @@ -690,14 +720,7 @@ void lcd_reset_status() { lcd_setstatusPGM(PSTR(""), -1); } void kill_screen(const char* lcd_msg) { lcd_init(); lcd_setalertstatusPGM(lcd_msg); - #if ENABLED(DOGLCD) - u8g.firstPage(); - do { - lcd_kill_screen(); - } while (u8g.nextPage()); - #else - lcd_kill_screen(); - #endif + lcd_kill_screen(); } #if ENABLED(ULTIPANEL) @@ -707,7 +730,7 @@ void kill_screen(const char* lcd_msg) { * Audio feedback for controller clicks * */ - void lcd_buzz(long duration, uint16_t freq) { + void lcd_buzz(const long duration, const uint16_t freq) { #if ENABLED(LCD_USE_I2C_BUZZER) lcd.buzz(duration, freq); #elif PIN_EXISTS(BEEPER) @@ -831,7 +854,7 @@ void kill_screen(const char* lcd_msg) { static int8_t bar_percent = 0; if (lcd_clicked) { lcd_goto_previous_menu(); - lcd_set_custom_characters(false); + lcd_set_custom_characters(CHARSET_MENU); return; } bar_percent += (int8_t)encoderPosition; @@ -991,6 +1014,10 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM(submenu, MSG_INFO_MENU, lcd_info_menu); #endif + #if ENABLED(LED_CONTROL_MENU) + MENU_ITEM(submenu, MSG_LED_CONTROL, lcd_led_menu); + #endif + END_MENU(); } @@ -1011,6 +1038,44 @@ void kill_screen(const char* lcd_msg) { } #endif + #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) || ENABLED(MESH_EDIT_GFX_OVERLAY) + + void _lcd_zoffset_overlay_gfx(const float zvalue) { + // Determine whether the user is raising or lowering the nozzle. + static int8_t dir; + static float old_zvalue; + if (zvalue != old_zvalue) { + dir = zvalue ? zvalue < old_zvalue ? -1 : 1 : 0; + old_zvalue = zvalue; + } + + #if ENABLED(OVERLAY_GFX_REVERSE) + const unsigned char *rot_up = ccw_bmp, *rot_down = cw_bmp; + #else + const unsigned char *rot_up = cw_bmp, *rot_down = ccw_bmp; + #endif + + #if ENABLED(USE_BIG_EDIT_FONT) + const int left = 0, right = 45, nozzle = 95; + #else + const int left = 5, right = 90, nozzle = 60; + #endif + + // Draw a representation of the nozzle + if (PAGE_CONTAINS(3, 16)) u8g.drawBitmapP(nozzle + 6, 4 - dir, 2, 12, nozzle_bmp); + if (PAGE_CONTAINS(20, 20)) u8g.drawBitmapP(nozzle + 0, 20, 3, 1, offset_bedline_bmp); + + // Draw cw/ccw indicator and up/down arrows. + if (PAGE_CONTAINS(47, 62)) { + u8g.drawBitmapP(left + 0, 47, 3, 16, rot_down); + u8g.drawBitmapP(right + 0, 47, 3, 16, rot_up); + u8g.drawBitmapP(right + 20, 48 - dir, 2, 13, up_arrow_bmp); + u8g.drawBitmapP(left + 20, 49 - dir, 2, 13, down_arrow_bmp); + } + } + + #endif // BABYSTEP_ZPROBE_GFX_OVERLAY || MESH_EDIT_GFX_OVERLAY + #if ENABLED(BABYSTEPPING) void _lcd_babystep(const AxisEnum axis, const char* msg) { @@ -1036,48 +1101,6 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) - void _lcd_babystep_zoffset_overlay(const float zprobe_zoffset) { - // Determine whether the user is raising or lowering the nozzle. - static int dir = 0; - static float old_zprobe_zoffset = 0; - if (zprobe_zoffset != old_zprobe_zoffset) { - dir = (zprobe_zoffset > old_zprobe_zoffset) ? 1 : -1; - old_zprobe_zoffset = zprobe_zoffset; - } - - #if ENABLED(BABYSTEP_ZPROBE_GFX_REVERSE) - const unsigned char* rot_up = ccw_bmp; - const unsigned char* rot_down = cw_bmp; - #else - const unsigned char* rot_up = cw_bmp; - const unsigned char* rot_down = ccw_bmp; - #endif - - #if ENABLED(USE_BIG_EDIT_FONT) - const int left = 0, - right = 45, - nozzle = 95; - #else - const int left = 5, - right = 90, - nozzle = 60; - #endif - - // Draw a representation of the nozzle - if (PAGE_CONTAINS(3, 16)) u8g.drawBitmapP(nozzle + 6, 4 - dir, 2, 12, nozzle_bmp); - if (PAGE_CONTAINS(20, 20)) u8g.drawBitmapP(nozzle + 0, 20, 3, 1, offset_bedline_bmp); - - // Draw cw/ccw indicator and up/down arrows. - if (PAGE_CONTAINS(47, 62)) { - u8g.drawBitmapP(left + 0, 47, 3, 16, rot_down); - u8g.drawBitmapP(right + 0, 47, 3, 16, rot_up); - u8g.drawBitmapP(right + 20, 48 - dir, 2, 13, up_arrow_bmp); - u8g.drawBitmapP(left + 20, 49 - dir, 2, 13, down_arrow_bmp); - } - } - #endif // BABYSTEP_ZPROBE_GFX_OVERLAY - void lcd_babystep_zoffset() { if (lcd_clicked) { return lcd_goto_previous_menu_no_defer(); } defer_return_to_status = true; @@ -1089,18 +1112,17 @@ void kill_screen(const char* lcd_msg) { const float new_zoffset = zprobe_zoffset + planner.steps_to_mm[Z_AXIS] * babystep_increment; if (WITHIN(new_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { - if (planner.abl_enabled) + if (planner.leveling_active) thermalManager.babystep_axis(Z_AXIS, babystep_increment); zprobe_zoffset = new_zoffset; - refresh_zprobe_zoffset(true); lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; } } if (lcdDrawUpdate) { lcd_implementation_drawedit(PSTR(MSG_ZPROBE_ZOFFSET), ftostr43sign(zprobe_zoffset)); #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) - _lcd_babystep_zoffset_overlay(zprobe_zoffset); + _lcd_zoffset_overlay_gfx(zprobe_zoffset); #endif } } @@ -1135,8 +1157,12 @@ void kill_screen(const char* lcd_msg) { mesh_edit_value = float(rounded - (rounded % 5L)) / 1000.0; } - if (lcdDrawUpdate) + if (lcdDrawUpdate) { lcd_implementation_drawedit(msg, ftostr43sign(mesh_edit_value)); + #if ENABLED(MESH_EDIT_GFX_OVERLAY) + _lcd_zoffset_overlay_gfx(mesh_edit_value); + #endif + } } void _lcd_mesh_edit_NOP() { @@ -1150,7 +1176,7 @@ void kill_screen(const char* lcd_msg) { return mesh_edit_value; } - void lcd_mesh_edit_setup(float initial) { + void lcd_mesh_edit_setup(const float initial) { mesh_edit_value = mesh_edit_accumulator = initial; lcd_goto_screen(_lcd_mesh_edit_NOP); } @@ -1221,6 +1247,31 @@ void kill_screen(const char* lcd_msg) { #endif // ADVANCED_PAUSE_FEATURE + // First Fan Speed title in "Tune" and "Control>Temperature" menus + #if FAN_COUNT > 0 && HAS_FAN0 + #if FAN_COUNT > 1 + #define FAN_SPEED_1_SUFFIX " 1" + #else + #define FAN_SPEED_1_SUFFIX "" + #endif + #endif + + // Refresh the E factor after changing flow + inline void _lcd_refresh_e_factor_0() { planner.refresh_e_factor(0); } + #if EXTRUDERS > 1 + inline void _lcd_refresh_e_factor() { planner.refresh_e_factor(active_extruder); } + inline void _lcd_refresh_e_factor_1() { planner.refresh_e_factor(1); } + #if EXTRUDERS > 2 + inline void _lcd_refresh_e_factor_2() { planner.refresh_e_factor(2); } + #if EXTRUDERS > 3 + inline void _lcd_refresh_e_factor_3() { planner.refresh_e_factor(3); } + #if EXTRUDERS > 4 + inline void _lcd_refresh_e_factor_4() { planner.refresh_e_factor(4); } + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + /** * * "Tune" submenu @@ -1276,18 +1327,22 @@ void kill_screen(const char* lcd_msg) { // #if FAN_COUNT > 0 #if HAS_FAN0 - #if FAN_COUNT > 1 - #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" - #else - #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED FAN_SPEED_1_SUFFIX, &fanSpeeds[0], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED FAN_SPEED_1_SUFFIX, &new_fanSpeeds[0], 3, 255); #endif - MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); #endif #if HAS_FAN1 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED " 2", &new_fanSpeeds[1], 3, 255); + #endif #endif #if HAS_FAN2 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED " 3", &new_fanSpeeds[2], 3, 255); + #endif #endif #endif // FAN_COUNT > 0 @@ -1296,17 +1351,17 @@ void kill_screen(const char* lcd_msg) { // Flow [1-5]: // #if EXTRUDERS == 1 - MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[0], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW, &planner.flow_percentage[0], 10, 999, _lcd_refresh_e_factor_0); #else // EXTRUDERS > 1 - MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[active_extruder], 10, 999); - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N1, &flow_percentage[0], 10, 999); - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N2, &flow_percentage[1], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW, &planner.flow_percentage[active_extruder], 10, 999, _lcd_refresh_e_factor); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N1, &planner.flow_percentage[0], 10, 999, _lcd_refresh_e_factor_0); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N2, &planner.flow_percentage[1], 10, 999, _lcd_refresh_e_factor_1); #if EXTRUDERS > 2 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N3, &flow_percentage[2], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N3, &planner.flow_percentage[2], 10, 999, _lcd_refresh_e_factor_2); #if EXTRUDERS > 3 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N4, &flow_percentage[3], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N4, &planner.flow_percentage[3], 10, 999, _lcd_refresh_e_factor_3); #if EXTRUDERS > 4 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N5, &flow_percentage[4], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N5, &planner.flow_percentage[4], 10, 999, _lcd_refresh_e_factor_4); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 @@ -1630,11 +1685,6 @@ void kill_screen(const char* lcd_msg) { static void lcd_load_settings() { lcd_completion_feedback(settings.load()); } #endif - #if HAS_BED_PROBE && DISABLED(BABYSTEP_ZPROBE_OFFSET) - static void lcd_refresh_zprobe_zoffset() { refresh_zprobe_zoffset(); } - #endif - - #if ENABLED(LEVEL_BED_CORNERS) /** @@ -1642,7 +1692,7 @@ void kill_screen(const char* lcd_msg) { */ static int8_t bed_corner; void _lcd_goto_next_corner() { - line_to_z(LOGICAL_Z_POSITION(4.0)); + line_to_z(4.0); switch (bed_corner) { case 0: current_position[X_AXIS] = X_MIN_BED + 10; @@ -1659,7 +1709,7 @@ void kill_screen(const char* lcd_msg) { break; } planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder); - line_to_z(LOGICAL_Z_POSITION(0.0)); + line_to_z(0.0); if (++bed_corner > 3) bed_corner = 0; } @@ -1698,59 +1748,34 @@ void kill_screen(const char* lcd_msg) { #endif ); + bool lcd_wait_for_move; + + // + // Bed leveling is done. Wait for G29 to complete. + // A flag is used so that this can release control + // and allow the command queue to be processed. + // + // When G29 finishes the last move: + // - Raise Z to the "manual probe height" + // - Don't return until done. // - // Raise Z to the "manual probe height" - // Don't return until done. // ** This blocks the command queue! ** // - void _lcd_after_probing() { - #if MANUAL_PROBE_HEIGHT > 0 - line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); - #endif - // Display "Done" screen and wait for moves to complete - #if MANUAL_PROBE_HEIGHT > 0 || ENABLED(MESH_BED_LEVELING) - lcd_synchronize(PSTR(MSG_LEVEL_BED_DONE)); - #endif - lcd_goto_previous_menu(); - lcd_completion_feedback(); - defer_return_to_status = false; - //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); + void _lcd_level_bed_done() { + if (!lcd_wait_for_move) { + #if MANUAL_PROBE_HEIGHT > 0 && DISABLED(MESH_BED_LEVELING) + // Display "Done" screen and wait for moves to complete + line_to_z(Z_MIN_POS + MANUAL_PROBE_HEIGHT); + lcd_synchronize(PSTR(MSG_LEVEL_BED_DONE)); + #endif + lcd_goto_previous_menu(); + lcd_completion_feedback(); + defer_return_to_status = false; + } + if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_LEVEL_BED_DONE)); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; } - #if ENABLED(MESH_BED_LEVELING) - - // Utility to go to the next mesh point - inline void _manual_probe_goto_xy(float x, float y) { - #if MANUAL_PROBE_HEIGHT > 0 - const float prev_z = current_position[Z_AXIS]; - line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); - #endif - current_position[X_AXIS] = LOGICAL_X_POSITION(x); - current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); - planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); - #if MANUAL_PROBE_HEIGHT > 0 - line_to_z(prev_z); - #endif - lcd_synchronize(); - } - - #elif ENABLED(PROBE_MANUALLY) - - bool lcd_wait_for_move; - - // - // Bed leveling is done. Wait for G29 to complete. - // A flag is used so that this can release control - // and allow the command queue to be processed. - // - void _lcd_level_bed_done() { - if (!lcd_wait_for_move) _lcd_after_probing(); - if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_DONE)); - lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; - } - - #endif - void _lcd_level_goto_next_point(); /** @@ -1762,46 +1787,24 @@ void kill_screen(const char* lcd_msg) { if (lcd_clicked) { // - // Save the current Z position + // Save the current Z position and move // - #if ENABLED(MESH_BED_LEVELING) - - // - // MBL records the position but doesn't move to the next one - // - - mbl.set_zigzag_z(manual_probe_index, current_position[Z_AXIS]); - - #endif - // If done... if (++manual_probe_index >= total_probe_points) { - + // + // The last G29 records the point and enables bed leveling + // + lcd_wait_for_move = true; + lcd_goto_screen(_lcd_level_bed_done); #if ENABLED(PROBE_MANUALLY) - - // - // The last G29 will record and enable but not move. - // - lcd_wait_for_move = true; enqueue_and_echo_commands_P(PSTR("G29 V1")); - lcd_goto_screen(_lcd_level_bed_done); - #elif ENABLED(MESH_BED_LEVELING) - - _lcd_after_probing(); - - mbl.set_has_mesh(true); - mesh_probing_done(); - + enqueue_and_echo_commands_P(PSTR("G29 S2")); #endif - } - else { - // MESH_BED_LEVELING: Z already stored, just move - // PROBE_MANUALLY: Send G29 to record Z, then move + else _lcd_level_goto_next_point(); - } return; } @@ -1829,7 +1832,6 @@ void kill_screen(const char* lcd_msg) { /** * Step 6: Display "Next point: 1 / 9" while waiting for move to finish */ - void _lcd_level_bed_moving() { if (lcdDrawUpdate) { char msg[10]; @@ -1837,39 +1839,22 @@ void kill_screen(const char* lcd_msg) { lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); } lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; - #if ENABLED(PROBE_MANUALLY) - if (!lcd_wait_for_move) lcd_goto_screen(_lcd_level_bed_get_z); - #endif + if (!lcd_wait_for_move) lcd_goto_screen(_lcd_level_bed_get_z); } /** * Step 5: Initiate a move to the next point */ void _lcd_level_goto_next_point() { - // Set the menu to display ahead of blocking call lcd_goto_screen(_lcd_level_bed_moving); - #if ENABLED(MESH_BED_LEVELING) - - int8_t px, py; - mbl.zigzag(manual_probe_index, px, py); - - // Controls the loop until the move is done - _manual_probe_goto_xy( - LOGICAL_X_POSITION(mbl.index_to_xpos[px]), - LOGICAL_Y_POSITION(mbl.index_to_ypos[py]) - ); - - // After the blocking function returns, change menus - lcd_goto_screen(_lcd_level_bed_get_z); - - #elif ENABLED(PROBE_MANUALLY) - - // G29 Records Z, moves, and signals when it pauses - lcd_wait_for_move = true; + // G29 Records Z, moves, and signals when it pauses + lcd_wait_for_move = true; + #if ENABLED(PROBE_MANUALLY) enqueue_and_echo_commands_P(PSTR("G29 V1")); - + #elif ENABLED(MESH_BED_LEVELING) + enqueue_and_echo_commands_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1")); #endif } @@ -1909,11 +1894,12 @@ void kill_screen(const char* lcd_msg) { enqueue_and_echo_commands_P(PSTR("G28")); } - static bool _level_state; - void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(_level_state); } + static bool new_level_state; + void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(new_level_state); } #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void _lcd_set_z_fade_height() { set_z_fade_height(planner.z_fade_height); } + static float new_z_fade_height; + void _lcd_set_z_fade_height() { set_z_fade_height(new_z_fade_height); } #endif /** @@ -1934,16 +1920,18 @@ void kill_screen(const char* lcd_msg) { START_MENU(); MENU_BACK(MSG_PREPARE); - if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) - MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); - else if (leveling_is_valid()) { - _level_state = leveling_is_active(); - MENU_ITEM_EDIT_CALLBACK(bool, MSG_BED_LEVELING, &_level_state, _lcd_toggle_bed_leveling); - } + #if DISABLED(MESH_BED_LEVELING) + if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + else + #endif + if (leveling_is_valid()) { + new_level_state = planner.leveling_active; + MENU_ITEM_EDIT_CALLBACK(bool, MSG_BED_LEVELING, &new_level_state, _lcd_toggle_bed_leveling); + } #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - set_z_fade_height(planner.z_fade_height); - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_Z_FADE_HEIGHT, &planner.z_fade_height, 0.0, 100.0, _lcd_set_z_fade_height); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_Z_FADE_HEIGHT, &new_z_fade_height, 0.0, 100.0, _lcd_set_z_fade_height); #endif // @@ -1956,7 +1944,7 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(BABYSTEP_ZPROBE_OFFSET) MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); #elif HAS_BED_PROBE - MENU_ITEM_EDIT_CALLBACK(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, lcd_refresh_zprobe_zoffset); + MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); #endif MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue); @@ -1964,7 +1952,7 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(LEVEL_BED_CORNERS) // Move to the next corner for leveling if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) - MENU_ITEM(function, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); + MENU_ITEM(submenu, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); #endif #if ENABLED(EEPROM_SETTINGS) @@ -1974,6 +1962,13 @@ void kill_screen(const char* lcd_msg) { END_MENU(); } + void _lcd_goto_bed_leveling() { + lcd_goto_screen(lcd_bed_leveling); + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + new_z_fade_height = planner.z_fade_height; + #endif + } + #elif ENABLED(AUTO_BED_LEVELING_UBL) void _lcd_ubl_level_bed(); @@ -2306,11 +2301,12 @@ void kill_screen(const char* lcd_msg) { void _lcd_ubl_map_homing() { defer_return_to_status = true; - ubl_lcd_map_control = true; // Return to the map screen if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT < 3 ? 0 : (LCD_HEIGHT > 4 ? 2 : 1), PSTR(MSG_LEVEL_BED_HOMING)); lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; - if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + ubl.lcd_map_control = true; // Return to the map screen lcd_goto_screen(_lcd_ubl_output_map_lcd); + } } /** @@ -2329,8 +2325,8 @@ void kill_screen(const char* lcd_msg) { * UBL LCD Map Movement */ void ubl_map_move_to_xy() { - current_position[X_AXIS] = LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])); - current_position[Y_AXIS] = LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])); + current_position[X_AXIS] = pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]); + current_position[Y_AXIS] = pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]); planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); } @@ -2340,6 +2336,19 @@ void kill_screen(const char* lcd_msg) { void set_current_from_steppers_for_axis(const AxisEnum axis); void sync_plan_position(); + void _lcd_do_nothing() {} + void _lcd_hard_stop() { + stepper.quick_stop(); + const screenFunc_t old_screen = currentScreen; + currentScreen = _lcd_do_nothing; + while (planner.movesplanned()) idle(); + currentScreen = old_screen; + stepper.cleaning_buffer_counter = 0; + set_current_from_steppers_for_axis(ALL_AXES); + sync_plan_position(); + refresh_cmd_timeout(); + } + void _lcd_ubl_output_map_lcd() { static int16_t step_scaler = 0; @@ -2384,15 +2393,10 @@ void kill_screen(const char* lcd_msg) { if (lcdDrawUpdate) { lcd_implementation_ubl_plot(x_plot, y_plot); - ubl_map_move_to_xy(); // Move to current location + if (planner.movesplanned()) // If the nozzle is already moving, cancel the move. + _lcd_hard_stop(); - if (planner.movesplanned() > 1) { // if the nozzle is moving, cancel the move. There is a new location - stepper.quick_stop(); - set_current_from_steppers_for_axis(ALL_AXES); - sync_plan_position(); - ubl_map_move_to_xy(); // Move to new location - refresh_cmd_timeout(); - } + ubl_map_move_to_xy(); // Move to new location } } @@ -2519,7 +2523,7 @@ void kill_screen(const char* lcd_msg) { // Move Axis // #if ENABLED(DELTA) - if (axis_homed[Z_AXIS]) + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) #endif MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu); @@ -2542,15 +2546,20 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(PROBE_MANUALLY) if (!g29_in_progress) #endif - MENU_ITEM(submenu, MSG_BED_LEVELING, lcd_bed_leveling); - #else - #if PLANNER_LEVELING - MENU_ITEM(gcode, MSG_BED_LEVELING, PSTR("G28\nG29")); - #endif - #if ENABLED(LEVEL_BED_CORNERS) - if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) - MENU_ITEM(function, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); - #endif + MENU_ITEM(submenu, MSG_BED_LEVELING, + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + _lcd_goto_bed_leveling + #else + lcd_bed_leveling + #endif + ); + #elif PLANNER_LEVELING && DISABLED(PROBE_MANUALLY) + MENU_ITEM(gcode, MSG_BED_LEVELING, PSTR("G28\nG29")); + #endif + + #if ENABLED(LEVEL_BED_CORNERS) && DISABLED(LCD_BED_LEVELING) + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + MENU_ITEM(function, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); #endif #if HAS_M206_COMMAND @@ -2628,7 +2637,7 @@ void kill_screen(const char* lcd_msg) { // // Delta Calibration // - #if ENABLED(DELTA_CALIBRATION_MENU) + #if ENABLED(DELTA_CALIBRATION_MENU) || ENABLED(DELTA_AUTO_CALIBRATION) MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, lcd_delta_calibrate_menu); #endif @@ -2637,10 +2646,44 @@ void kill_screen(const char* lcd_msg) { float move_menu_scale; - #if ENABLED(DELTA_CALIBRATION_MENU) + #if ENABLED(DELTA_CALIBRATION_MENU) || (ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE) void lcd_move_z(); - void lcd_delta_calibrate_menu(); + + void _man_probe_pt(const float &rx, const float &ry) { + #if HAS_LEVELING + reset_bed_level(); // After calibration bed-level data is no longer valid + #endif + + line_to_z((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5); + current_position[X_AXIS] = rx; + current_position[Y_AXIS] = ry; + line_to_current_z(); + line_to_z(Z_CLEARANCE_BETWEEN_PROBES); + + lcd_synchronize(); + move_menu_scale = PROBE_MANUALLY_STEP; + lcd_goto_screen(lcd_move_z); + } + + #endif // DELTA_CALIBRATION_MENU || (DELTA_AUTO_CALIBRATION && !HAS_BED_PROBE) + + #if ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE + + float lcd_probe_pt(const float &rx, const float &ry) { + _man_probe_pt(rx, ry); + KEEPALIVE_STATE(PAUSED_FOR_USER); + defer_return_to_status = true; + wait_for_user = true; + while (wait_for_user) idle(); + KEEPALIVE_STATE(IN_HANDLER); + lcd_goto_previous_menu_no_defer(); + return current_position[Z_AXIS]; + } + + #endif // DELTA_AUTO_CALIBRATION && !HAS_BED_PROBE + + #if ENABLED(DELTA_CALIBRATION_MENU) void _lcd_calibrate_homing() { if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_LEVEL_BED_HOMING)); @@ -2658,60 +2701,27 @@ void kill_screen(const char* lcd_msg) { lcd_goto_screen(_lcd_calibrate_homing); } - void _man_probe_pt(const float &lx, const float &ly) { - #if HAS_LEVELING - reset_bed_level(); // After calibration bed-level data is no longer valid - #endif - - float z_dest = LOGICAL_Z_POSITION((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5); - line_to_z(z_dest); - current_position[X_AXIS] = LOGICAL_X_POSITION(lx); - current_position[Y_AXIS] = LOGICAL_Y_POSITION(ly); - line_to_current_z(); - z_dest = LOGICAL_Z_POSITION(Z_CLEARANCE_BETWEEN_PROBES); - line_to_z(z_dest); - - lcd_synchronize(); - move_menu_scale = PROBE_MANUALLY_STEP; - lcd_goto_screen(lcd_move_z); - } - - float lcd_probe_pt(const float &lx, const float &ly) { - _man_probe_pt(lx, ly); - KEEPALIVE_STATE(PAUSED_FOR_USER); - defer_return_to_status = true; - wait_for_user = true; - while (wait_for_user) idle(); - KEEPALIVE_STATE(IN_HANDLER); - lcd_goto_previous_menu_no_defer(); - return current_position[Z_AXIS]; - } - void _goto_tower_x() { _man_probe_pt(cos(RADIANS(210)) * delta_calibration_radius, sin(RADIANS(210)) * delta_calibration_radius); } void _goto_tower_y() { _man_probe_pt(cos(RADIANS(330)) * delta_calibration_radius, sin(RADIANS(330)) * delta_calibration_radius); } void _goto_tower_z() { _man_probe_pt(cos(RADIANS( 90)) * delta_calibration_radius, sin(RADIANS( 90)) * delta_calibration_radius); } void _goto_center() { _man_probe_pt(0,0); } - static float _delta_height = DELTA_HEIGHT; - void _lcd_set_delta_height() { - home_offset[Z_AXIS] = _delta_height - DELTA_HEIGHT; - update_software_endstops(Z_AXIS); - } + #endif // DELTA_CALIBRATION_MENU + + #if ENABLED(DELTA_CALIBRATION_MENU) || ENABLED(DELTA_AUTO_CALIBRATION) void lcd_delta_settings() { START_MENU(); MENU_BACK(MSG_DELTA_CALIBRATE); - float Tz = 0.00; - MENU_ITEM_EDIT(float52, MSG_DELTA_DIAG_ROG, &delta_diagonal_rod, DELTA_DIAGONAL_ROD - 5.0, DELTA_DIAGONAL_ROD + 5.0); - _delta_height = DELTA_HEIGHT + home_offset[Z_AXIS]; - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &_delta_height, _delta_height - 10.0, _delta_height + 10.0, _lcd_set_delta_height); - MENU_ITEM_EDIT(float43, "Ex", &endstop_adj[A_AXIS], -5.0, 5.0); - MENU_ITEM_EDIT(float43, "Ey", &endstop_adj[B_AXIS], -5.0, 5.0); - MENU_ITEM_EDIT(float43, "Ez", &endstop_adj[C_AXIS], -5.0, 5.0); - MENU_ITEM_EDIT(float52, MSG_DELTA_RADIUS, &delta_radius, DELTA_RADIUS - 5.0, DELTA_RADIUS + 5.0); - MENU_ITEM_EDIT(float43, "Tx", &delta_tower_angle_trim[A_AXIS], -5.0, 5.0); - MENU_ITEM_EDIT(float43, "Ty", &delta_tower_angle_trim[B_AXIS], -5.0, 5.0); - MENU_ITEM_EDIT(float43, "Tz", &delta_tower_angle_trim[C_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_DIAG_ROD, &delta_diagonal_rod, delta_diagonal_rod - 5.0, delta_diagonal_rod + 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &delta_height, delta_height - 10.0, delta_height + 10.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ex", &delta_endstop_adj[A_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ey", &delta_endstop_adj[B_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ez", &delta_endstop_adj[C_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_RADIUS, &delta_radius, delta_radius - 5.0, delta_radius + 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Tx", &delta_tower_angle_trim[A_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Ty", &delta_tower_angle_trim[B_AXIS], -5.0, 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float43, "Tz", &delta_tower_angle_trim[C_AXIS], -5.0, 5.0, recalc_delta_settings); END_MENU(); } @@ -2719,7 +2729,6 @@ void kill_screen(const char* lcd_msg) { START_MENU(); MENU_BACK(MSG_MAIN); #if ENABLED(DELTA_AUTO_CALIBRATION) - MENU_ITEM(submenu, MSG_DELTA_SETTINGS, lcd_delta_settings); MENU_ITEM(gcode, MSG_DELTA_AUTO_CALIBRATE, PSTR("G33")); MENU_ITEM(gcode, MSG_DELTA_HEIGHT_CALIBRATE, PSTR("G33 P1")); #if ENABLED(EEPROM_SETTINGS) @@ -2727,24 +2736,20 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings); #endif #endif - MENU_ITEM(submenu, MSG_AUTO_HOME, _lcd_delta_calibrate_home); - if (axis_homed[Z_AXIS]) { - MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_X, _goto_tower_x); - MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Y, _goto_tower_y); - MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Z, _goto_tower_z); - MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_CENTER, _goto_center); - } + MENU_ITEM(submenu, MSG_DELTA_SETTINGS, lcd_delta_settings); + #if ENABLED(DELTA_CALIBRATION_MENU) + MENU_ITEM(submenu, MSG_AUTO_HOME, _lcd_delta_calibrate_home); + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_X, _goto_tower_x); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Y, _goto_tower_y); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Z, _goto_tower_z); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_CENTER, _goto_center); + } + #endif END_MENU(); } - #endif // DELTA_CALIBRATION_MENU - - #if IS_KINEMATIC - extern float feedrate_mm_s; - extern float destination[XYZE]; - void set_destination_to_current(); - void prepare_move_to_destination(); - #endif + #endif // DELTA_CALIBRATION_MENU || DELTA_AUTO_CALIBRATION /** * If the most recent manual move hasn't been fed to the planner yet, @@ -2767,19 +2772,16 @@ void kill_screen(const char* lcd_msg) { #endif // Set movement on a single axis - set_destination_to_current(); + set_destination_from_current(); destination[manual_move_axis] += manual_move_offset; // Reset for the next move manual_move_offset = 0.0; manual_move_axis = (int8_t)NO_AXIS; - // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to - // move_to_destination. This will cause idle() to be called, which can then call this function while the - // previous invocation is being blocked. Modifications to manual_move_offset shouldn't be made while - // processing_manual_move is true or the planner will get out of sync. + // Set a blocking flag so no new moves can be added until all segments are done processing_manual_move = true; - prepare_move_to_destination(); // will call set_current_to_destination + prepare_move_to_destination(); // will call set_current_from_destination() processing_manual_move = false; feedrate_mm_s = old_feedrate; @@ -2831,17 +2833,35 @@ void kill_screen(const char* lcd_msg) { float min = current_position[axis] - 1000, max = current_position[axis] + 1000; - #if HAS_SOFTWARE_ENDSTOPS - // Limit to software endstops, if enabled - if (soft_endstops_enabled) { - #if ENABLED(MIN_SOFTWARE_ENDSTOPS) - min = soft_endstop_min[axis]; - #endif - #if ENABLED(MAX_SOFTWARE_ENDSTOPS) - max = soft_endstop_max[axis]; - #endif + // Limit to software endstops, if enabled + #if ENABLED(MIN_SOFTWARE_ENDSTOPS) || ENABLED(MAX_SOFTWARE_ENDSTOPS) + if (soft_endstops_enabled) switch (axis) { + case X_AXIS: + #if ENABLED(MIN_SOFTWARE_ENDSTOP_X) + min = soft_endstop_min[X_AXIS]; + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_X) + max = soft_endstop_max[X_AXIS]; + #endif + break; + case Y_AXIS: + #if ENABLED(MIN_SOFTWARE_ENDSTOP_Y) + min = soft_endstop_min[Y_AXIS]; + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_Y) + max = soft_endstop_max[Y_AXIS]; + #endif + break; + case Z_AXIS: + #if ENABLED(MIN_SOFTWARE_ENDSTOP_Z) + min = soft_endstop_min[Z_AXIS]; + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) + max = soft_endstop_max[Z_AXIS]; + #endif + default: break; } - #endif + #endif // MIN_SOFTWARE_ENDSTOPS || MAX_SOFTWARE_ENDSTOPS // Delta limits XY based on the current offset from center // This assumes the center is 0,0 @@ -3112,7 +3132,7 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM(submenu, MSG_FILAMENT, lcd_control_filament_menu); #if HAS_LCD_CONTRAST - MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, (int*)&lcd_contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, lcd_callback_set_contrast, true); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, &lcd_contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, lcd_callback_set_contrast, true); #endif #if ENABLED(FWRETRACT) MENU_ITEM(submenu, MSG_RETRACT, lcd_control_retract_menu); @@ -3265,18 +3285,22 @@ void kill_screen(const char* lcd_msg) { // #if FAN_COUNT > 0 #if HAS_FAN0 - #if FAN_COUNT > 1 - #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" - #else - #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED FAN_SPEED_1_SUFFIX, &fanSpeeds[0], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED FAN_SPEED_1_SUFFIX, &new_fanSpeeds[0], 3, 255); #endif - MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); #endif #if HAS_FAN1 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED " 2", &new_fanSpeeds[1], 3, 255); + #endif #endif #if HAS_FAN2 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + #if ENABLED(EXTRA_FAN_SPEED) + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED " 3", &new_fanSpeeds[2], 3, 255); + #endif #endif #endif // FAN_COUNT > 0 @@ -3571,7 +3595,7 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(BABYSTEP_ZPROBE_OFFSET) MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); #elif HAS_BED_PROBE - MENU_ITEM_EDIT_CALLBACK(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, lcd_refresh_zprobe_zoffset); + MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); #endif // M203 / M205 - Feedrate items @@ -3607,20 +3631,21 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM_EDIT(float3, MSG_ADVANCE_K, &planner.extruder_advance_k, 0, 999); #endif - MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &volumetric_enabled, calculate_volumetric_multipliers); + MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &parser.volumetric_enabled, planner.calculate_volumetric_multipliers); - if (volumetric_enabled) { + if (parser.volumetric_enabled) { #if EXTRUDERS == 1 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &planner.filament_size[0], 1.5, 3.25, planner.calculate_volumetric_multipliers); #else // EXTRUDERS > 1 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &filament_size[1], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &planner.filament_size[active_extruder], 1.5, 3.25, planner.calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &planner.filament_size[0], 1.5, 3.25, planner.calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &planner.filament_size[1], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 2 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &filament_size[2], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &planner.filament_size[2], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 3 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &filament_size[3], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &planner.filament_size[3], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 4 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E5, &filament_size[4], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E5, &planner.filament_size[4], 1.5, 3.25, planner.calculate_volumetric_multipliers); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 @@ -3652,6 +3677,9 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &swap_retract_recover_length, -100, 100); #endif MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &swap_retract_recover_feedrate_mm_s, 1, 999); + #endif END_MENU(); } @@ -3667,7 +3695,7 @@ void kill_screen(const char* lcd_msg) { #endif void lcd_sd_updir() { - card.updir(); + encoderPosition = card.updir() ? ENCODER_STEPS_PER_MENU_ITEM : 0; encoderTopLine = 0; screen_changed = true; lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; @@ -3678,10 +3706,38 @@ void kill_screen(const char* lcd_msg) { * "Print from SD" submenu * */ + + #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) + uint32_t last_sdfile_encoderPosition = 0xFFFF; + + void lcd_reselect_last_file() { + if (last_sdfile_encoderPosition == 0xFFFF) return; + #if ENABLED(DOGLCD) + // Some of this is a hack to force the screen update to work. + // TODO: Fix the real issue that causes this! + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + _lcd_synchronize(); + safe_delay(50); + _lcd_synchronize(); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + drawing_screen = screen_changed = true; + #endif + + lcd_goto_screen(lcd_sdcard_menu, last_sdfile_encoderPosition); + defer_return_to_status = true; + last_sdfile_encoderPosition = 0xFFFF; + + #if ENABLED(DOGLCD) + lcd_update(); + #endif + } + #endif + void lcd_sdcard_menu() { ENCODER_DIRECTION_MENUS(); - if (!lcdDrawUpdate && !lcd_clicked) return; // nothing to do (so don't thrash the SD card) - const uint16_t fileCnt = card.getnrfilenames(); + + const uint16_t fileCnt = card.get_num_Files(); + START_MENU(); MENU_BACK(MSG_MAIN); card.getWorkDirName(); @@ -3887,6 +3943,66 @@ void kill_screen(const char* lcd_msg) { } #endif // LCD_INFO_MENU + /** + * + * LED Menu + * + */ + + #if ENABLED(LED_CONTROL_MENU) + + #if ENABLED(LED_COLOR_PRESETS) + + void lcd_led_presets_menu() { + START_MENU(); + #if LCD_HEIGHT > 2 + STATIC_ITEM(MSG_LED_PRESETS, true, true); + #endif + MENU_BACK(MSG_LED_CONTROL); + MENU_ITEM(function, MSG_SET_LEDS_WHITE, leds.set_white); + MENU_ITEM(function, MSG_SET_LEDS_RED, leds.set_red); + MENU_ITEM(function, MSG_SET_LEDS_ORANGE, leds.set_orange); + MENU_ITEM(function, MSG_SET_LEDS_YELLOW,leds.set_yellow); + MENU_ITEM(function, MSG_SET_LEDS_GREEN, leds.set_green); + MENU_ITEM(function, MSG_SET_LEDS_BLUE, leds.set_blue); + MENU_ITEM(function, MSG_SET_LEDS_INDIGO, leds.set_indigo); + MENU_ITEM(function, MSG_SET_LEDS_VIOLET, leds.set_violet); + END_MENU(); + } + #endif // LED_COLOR_PRESETS + + void lcd_led_custom_menu() { + START_MENU(); + MENU_BACK(MSG_LED_CONTROL); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_INTENSITY_R, &leds.color.r, 0, 255, leds.update, true); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_INTENSITY_G, &leds.color.g, 0, 255, leds.update, true); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_INTENSITY_B, &leds.color.b, 0, 255, leds.update, true); + #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED) + MENU_ITEM_EDIT_CALLBACK(int8, MSG_INTENSITY_W, &leds.color.w, 0, 255, leds.update, true); + #if ENABLED(NEOPIXEL_LED) + MENU_ITEM_EDIT_CALLBACK(int8, MSG_LED_BRIGHTNESS, &leds.color.i, 0, 255, leds.update, true); + #endif + #endif + END_MENU(); + } + + void lcd_led_menu() { + START_MENU(); + MENU_BACK(MSG_MAIN); + if (leds.lights_on) + MENU_ITEM(function, MSG_LEDS_OFF, leds.toggle); + else + MENU_ITEM(function, MSG_LEDS_ON, leds.toggle); + MENU_ITEM(function, MSG_SET_LEDS_DEFAULT, leds.set_default); + #if ENABLED(LED_COLOR_PRESETS) + MENU_ITEM(submenu, MSG_LED_PRESETS, lcd_led_presets_menu); + #endif + MENU_ITEM(submenu, MSG_CUSTOM_LEDS, lcd_led_custom_menu); + END_MENU(); + } + + #endif // LED_CONTROL_MENU + /** * * Filament Change Feature Screens @@ -4213,6 +4329,7 @@ void kill_screen(const char* lcd_msg) { } \ typedef void _name + DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01); DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1); DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1); DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0); @@ -4222,7 +4339,6 @@ void kill_screen(const char* lcd_msg) { DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0); DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52sign, 100.0); DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0); - DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01); /** * @@ -4232,31 +4348,29 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(ADC_KEYPAD) inline bool handle_adc_keypad() { - static uint8_t adc_steps = 0; + #define ADC_MIN_KEY_DELAY 100 if (buttons_reprapworld_keypad) { - if (adc_steps < 20) ++adc_steps; - lcd_quick_feedback(); lcdDrawUpdate = LCDVIEW_REDRAW_NOW; if (encoderDirection == -1) { // side effect which signals we are inside a menu if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) menu_action_back(); - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) lcd_return_to_status(); + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) { menu_action_back(); lcd_quick_feedback(); } + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) { lcd_return_to_status(); lcd_quick_feedback(); } } else { - const int8_t step = adc_steps > 19 ? 100 : adc_steps > 10 ? 10 : 1; - if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition += ENCODER_PULSES_PER_STEP * step; - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition -= ENCODER_PULSES_PER_STEP * step; - else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) encoderPosition = 0; + if (buttons_reprapworld_keypad & (EN_REPRAPWORLD_KEYPAD_DOWN|EN_REPRAPWORLD_KEYPAD_UP|EN_REPRAPWORLD_KEYPAD_RIGHT)) { + if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition += ENCODER_PULSES_PER_STEP; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition -= ENCODER_PULSES_PER_STEP; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) encoderPosition = 0; + } } #if ENABLED(ADC_KEYPAD_DEBUG) SERIAL_PROTOCOLLNPAIR("buttons_reprapworld_keypad = ", (uint32_t)buttons_reprapworld_keypad); SERIAL_PROTOCOLLNPAIR("encoderPosition = ", (uint32_t)encoderPosition); #endif + next_button_update_ms = millis() + ADC_MIN_KEY_DELAY; return true; } - else if (!thermalManager.current_ADCKey_raw) - adc_steps = 0; // reset stepping acceleration return false; } @@ -4329,6 +4443,9 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(SDSUPPORT) void menu_action_sdfile(const char* filename, char* longFilename) { + #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) + last_sdfile_encoderPosition = encoderPosition; // Save which file was selected for later use + #endif UNUSED(longFilename); card.openAndPrintFile(filename); lcd_return_to_status(); @@ -4337,7 +4454,8 @@ void kill_screen(const char* lcd_msg) { void menu_action_sddirectory(const char* filename, char* longFilename) { UNUSED(longFilename); card.chdir(filename); - encoderPosition = 0; + encoderTopLine = 0; + encoderPosition = 2 * ENCODER_STEPS_PER_MENU_ITEM; screen_changed = true; lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; } @@ -4354,11 +4472,7 @@ void kill_screen(const char* lcd_msg) { void lcd_init() { - lcd_implementation_init( - #if ENABLED(LCD_PROGRESS_BAR) - true - #endif - ); + lcd_implementation_init(); #if ENABLED(NEWPANEL) #if BUTTON_EXISTS(EN1) @@ -4487,14 +4601,20 @@ void lcd_update() { #if ENABLED(ULTIPANEL) static millis_t return_to_status_ms = 0; + + // Handle any queued Move Axis motion manage_manual_move(); + // Update button states for LCD_CLICKED, etc. + // After state changes the next button update + // may be delayed 300-500ms. lcd_buttons_update(); #if ENABLED(AUTO_BED_LEVELING_UBL) - const bool UBL_CONDITION = !ubl.has_control_of_lcd_panel; + // Don't run the debouncer if UBL owns the display + #define UBL_CONDITION !lcd_external_control #else - constexpr bool UBL_CONDITION = true; + #define UBL_CONDITION true #endif // If the action button is pressed... @@ -4527,7 +4647,7 @@ void lcd_update() { lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. #if ENABLED(LCD_PROGRESS_BAR) - currentScreen == lcd_status_screen + currentScreen == lcd_status_screen ? CHARSET_INFO : CHARSET_MENU #endif ); } @@ -4564,7 +4684,7 @@ void lcd_update() { #endif - bool encoderPastThreshold = (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP); + const bool encoderPastThreshold = (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP); if (encoderPastThreshold || lcd_clicked) { if (encoderPastThreshold) { int32_t encoderMultiplier = 1; @@ -4606,7 +4726,6 @@ void lcd_update() { // We arrive here every ~100ms when idling often enough. // Instead of tracking the changes simply redraw the Info Screen ~1 time a second. - static int8_t lcd_status_update_delay = 1; // first update one loop delayed if ( #if ENABLED(ULTIPANEL) currentScreen == lcd_status_screen && @@ -4622,31 +4741,39 @@ void lcd_update() { lcdDrawUpdate = LCDVIEW_REDRAW_NOW; } + #if ENABLED(SCROLL_LONG_FILENAMES) + // If scrolling of long file names is enabled and we are in the sd card menu, + // cause a refresh to occur until all the text has scrolled into view. + if (currentScreen == lcd_sdcard_menu && filename_scroll_pos < filename_scroll_max && !lcd_status_update_delay--) { + lcd_status_update_delay = 6; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + filename_scroll_pos++; + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + } + #endif + // then we want to use 1/2 of the time only. uint16_t bbr2 = planner.block_buffer_runtime() >> 1; #if ENABLED(DOGLCD) - if ((lcdDrawUpdate || drawing_screen) && (!bbr2 || (bbr2 > max_display_update_time))) + #define IS_DRAWING drawing_screen #else - if (lcdDrawUpdate && (!bbr2 || (bbr2 > max_display_update_time))) + #define IS_DRAWING false #endif - { - #if ENABLED(DOGLCD) - if (!drawing_screen) - #endif - { - switch (lcdDrawUpdate) { - case LCDVIEW_CALL_NO_REDRAW: - lcdDrawUpdate = LCDVIEW_NONE; - break; - case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) - case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) - lcdDrawUpdate = LCDVIEW_REDRAW_NOW; - case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT - case LCDVIEW_NONE: - break; - } // switch - } + + if ((lcdDrawUpdate || IS_DRAWING) && (!bbr2 || bbr2 > max_display_update_time)) { + + if (!IS_DRAWING) switch (lcdDrawUpdate) { + case LCDVIEW_CALL_NO_REDRAW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) + case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + case LCDVIEW_NONE: + break; + } // switch #if ENABLED(ADC_KEYPAD) buttons_reprapworld_keypad = 0; @@ -4658,14 +4785,18 @@ void lcd_update() { #define CURRENTSCREEN() lcd_status_screen() #endif - #if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display - if (!drawing_screen) { - u8g.firstPage(); - drawing_screen = 1; + #if ENABLED(DOGLCD) + if (!drawing_screen) { // If not already drawing pages + u8g.firstPage(); // Start the first page + drawing_screen = 1; // Flag as drawing pages } - lcd_setFont(FONT_MENU); - u8g.setColorIndex(1); - CURRENTSCREEN(); + lcd_setFont(FONT_MENU); // Setup font for every page draw + u8g.setColorIndex(1); // And reset the color + CURRENTSCREEN(); // Draw and process the current screen + + // The screen handler can clear drawing_screen for an action that changes the screen. + // If still drawing and there's another page, update max-time and return now. + // The nextPage will already be set up on the next call. if (drawing_screen && (drawing_screen = u8g.nextPage())) { NOLESS(max_display_update_time, millis() - ms); return; @@ -4673,6 +4804,9 @@ void lcd_update() { #else CURRENTSCREEN(); #endif + + // Keeping track of the longest time for an individual LCD update. + // Used to do screen throttling when the planner starts to fill up. NOLESS(max_display_update_time, millis() - ms); } @@ -4686,27 +4820,23 @@ void lcd_update() { #endif // ULTIPANEL - #if ENABLED(DOGLCD) - if (!drawing_screen) - #endif - { - switch (lcdDrawUpdate) { - case LCDVIEW_CLEAR_CALL_REDRAW: - lcd_implementation_clear(); - case LCDVIEW_CALL_REDRAW_NEXT: - lcdDrawUpdate = LCDVIEW_REDRAW_NOW; - break; - case LCDVIEW_REDRAW_NOW: - lcdDrawUpdate = LCDVIEW_NONE; - break; - case LCDVIEW_NONE: - break; - } // switch - } + if (!IS_DRAWING) switch (lcdDrawUpdate) { + case LCDVIEW_CLEAR_CALL_REDRAW: + lcd_implementation_clear(); + case LCDVIEW_CALL_REDRAW_NEXT: + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + break; + case LCDVIEW_REDRAW_NOW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_NONE: + break; + } // switch + } // ELAPSED(ms, next_lcd_update_ms) } -void pad_message_string() { +inline void pad_message_string() { uint8_t i = 0, j = 0; char c; while ((c = lcd_status_message[i]) && j < LCD_WIDTH) { @@ -4812,7 +4942,7 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } #define encrot3 1 #endif - #define GET_BUTTON_STATES(DST) \ + #define GET_SHIFT_BUTTON_STATES(DST) \ uint8_t new_##DST = 0; \ WRITE(SHIFT_LD, LOW); \ WRITE(SHIFT_LD, HIGH); \ @@ -4831,7 +4961,7 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } */ void lcd_buttons_update() { static uint8_t lastEncoderBits; - millis_t now = millis(); + const millis_t now = millis(); if (ELAPSED(now, next_button_update_ms)) { #if ENABLED(NEWPANEL) @@ -4912,13 +5042,15 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } #elif ENABLED(REPRAPWORLD_KEYPAD) - GET_BUTTON_STATES(buttons_reprapworld_keypad); + GET_SHIFT_BUTTON_STATES(buttons_reprapworld_keypad); #endif - #else - GET_BUTTON_STATES(buttons); - #endif // !NEWPANEL + #else // !NEWPANEL + + GET_SHIFT_BUTTON_STATES(buttons); + + #endif } // next_button_update_ms @@ -4949,7 +5081,7 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } case encrot3: ENCODER_SPIN(encrot2, encrot0); break; } #if ENABLED(AUTO_BED_LEVELING_UBL) - if (ubl.has_control_of_lcd_panel) { + if (lcd_external_control) { ubl.encoder_diff = encoderDiff; // Make the encoder's rotation available to G29's Mesh Editor encoderDiff = 0; // We are going to lie to the LCD Panel and claim the encoder // knob has not turned. @@ -4965,18 +5097,22 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } bool lcd_detected() { return true; } #endif - #if ENABLED(AUTO_BED_LEVELING_UBL) - - void chirp_at_user() { + #if ENABLED(G26_MESH_VALIDATION) + void lcd_chirp() { #if ENABLED(LCD_USE_I2C_BUZZER) lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); #elif PIN_EXISTS(BEEPER) buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); #endif } + #endif - bool ubl_lcd_clicked() { return LCD_CLICKED; } - + #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) + bool is_lcd_clicked() { return LCD_CLICKED; } + void wait_for_release() { + while (is_lcd_clicked()) safe_delay(50); + safe_delay(50); + } #endif #endif // ULTIPANEL diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index 0a50f173ae..ab2ce15a3c 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -23,10 +23,19 @@ #ifndef ULTRALCD_H #define ULTRALCD_H -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(ULTRA_LCD) + #include "Marlin.h" + + #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) + extern bool lcd_external_control; + #if ENABLED(G26_MESH_VALIDATION) + void lcd_chirp(); + #endif + #endif + #define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0) #define BUTTON_PRESSED(BN) !READ(BTN_## BN) @@ -50,7 +59,7 @@ inline void lcd_refresh() { lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; } #if HAS_BUZZER - void lcd_buzz(long duration, uint16_t freq); + void lcd_buzz(const long duration, const uint16_t freq); #endif #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 @@ -129,20 +138,19 @@ #define REPRAPWORLD_KEYPAD_MOVE_Z_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F3) #define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F2) - #define REPRAPWORLD_KEYPAD_MOVE_MENU (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1) #define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) #define REPRAPWORLD_KEYPAD_MOVE_X_RIGHT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) - #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE) #define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) #define REPRAPWORLD_KEYPAD_MOVE_X_LEFT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) #if ENABLED(ADC_KEYPAD) - #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1) - #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_MIDDLE + #define KEYPAD_HOME EN_REPRAPWORLD_KEYPAD_F1 + #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_MIDDLE #else - #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE) - #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_F1 + #define KEYPAD_HOME EN_REPRAPWORLD_KEYPAD_MIDDLE + #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_F1 #endif + #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & KEYPAD_HOME) #define REPRAPWORLD_KEYPAD_MOVE_MENU (buttons_reprapworld_keypad & KEYPAD_EN_C) #if BUTTON_EXISTS(ENC) @@ -168,6 +176,15 @@ #define LCD_CLICKED false #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) + bool is_lcd_clicked(); + void wait_for_release(); + #endif + + #if ENABLED(LCD_SET_PROGRESS_MANUALLY) && (ENABLED(LCD_PROGRESS_BAR) || ENABLED(DOGLCD)) + extern uint8_t progress_bar_percent; + #endif + #else // no LCD inline void lcd_update() {} @@ -190,15 +207,18 @@ void lcd_reset_status(); #if ENABLED(AUTO_BED_LEVELING_UBL) - extern bool ubl_lcd_map_control; - void lcd_mesh_edit_setup(float initial); + void lcd_mesh_edit_setup(const float initial); float lcd_mesh_edit(); void lcd_z_offset_edit_setup(float); float lcd_z_offset_edit(); #endif -#if ENABLED(DELTA_CALIBRATION_MENU) - float lcd_probe_pt(const float &lx, const float &ly); +#if ENABLED(DELTA_AUTO_CALIBRATION) && !HAS_BED_PROBE + float lcd_probe_pt(const float &rx, const float &ry); +#endif + +#if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) + void lcd_reselect_last_file(); #endif #endif // ULTRALCD_H diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h index 6f75143a0e..0cd66872b2 100644 --- a/Marlin/ultralcd_impl_DOGM.h +++ b/Marlin/ultralcd_impl_DOGM.h @@ -187,6 +187,10 @@ // U8GLIB_ST7565_64128n_2x_VIKI u8g(0); // using SW-SPI DOGLCD_MOSI != -1 && DOGLCD_SCK U8GLIB_ST7565_64128n_2x_VIKI u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // using SW-SPI //U8GLIB_NHD_C12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes HWSPI +#elif ENABLED(MKS_12864OLED_SSD1306) + // MKS 128x64 (SSD1306) OLED I2C LCD + U8GLIB_SSD1306_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes + //U8GLIB_SSD1306_128X64_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes #elif ENABLED(U8GLIB_SSD1306) // Generic support for SSD1306 OLED I2C LCDs //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes @@ -279,6 +283,10 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + #ifndef CUSTOM_BOOTSCREEN_TIMEOUT + #define CUSTOM_BOOTSCREEN_TIMEOUT 2500 + #endif + void lcd_custom_bootscreen() { u8g.firstPage(); do { @@ -287,39 +295,38 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { ( 64 - (CUSTOM_BOOTSCREEN_BMPHEIGHT)) /2, CEILING(CUSTOM_BOOTSCREEN_BMPWIDTH, 8), CUSTOM_BOOTSCREEN_BMPHEIGHT, custom_start_bmp); } while (u8g.nextPage()); + safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT); } #endif // SHOW_CUSTOM_BOOTSCREEN void lcd_bootscreen() { + #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + lcd_custom_bootscreen(); + #endif - static bool show_bootscreen = true; + #if ENABLED(START_BMPHIGH) + constexpr uint8_t offy = 0; + #else + constexpr uint8_t offy = DOG_CHAR_HEIGHT; + #endif - if (show_bootscreen) { - show_bootscreen = false; + const uint8_t offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2, + txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2; - #if ENABLED(START_BMPHIGH) - constexpr uint8_t offy = 0; + u8g.firstPage(); + do { + u8g.drawBitmapP(offx, offy, (START_BMPWIDTH + 7) / 8, START_BMPHEIGHT, start_bmp); + lcd_setFont(FONT_MENU); + #ifndef STRING_SPLASH_LINE2 + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT), STRING_SPLASH_LINE1); #else - constexpr uint8_t offy = DOG_CHAR_HEIGHT; + const uint8_t txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * (DOG_CHAR_WIDTH)) / 2; + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 3 / 2, STRING_SPLASH_LINE1); + u8g.drawStr(txt2X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 1 / 2, STRING_SPLASH_LINE2); #endif - - const uint8_t offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2, - txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2; - - u8g.firstPage(); - do { - u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp); - lcd_setFont(FONT_MENU); - #ifndef STRING_SPLASH_LINE2 - u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT), STRING_SPLASH_LINE1); - #else - const uint8_t txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * (DOG_CHAR_WIDTH)) / 2; - u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 3 / 2, STRING_SPLASH_LINE1); - u8g.drawStr(txt2X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 1 / 2, STRING_SPLASH_LINE2); - #endif - } while (u8g.nextPage()); - } + } while (u8g.nextPage()); + safe_delay(BOOTSCREEN_TIMEOUT); } #endif // SHOW_BOOTSCREEN @@ -350,25 +357,20 @@ static void lcd_implementation_init() { #elif ENABLED(LCD_SCREEN_ROT_270) u8g.setRot270(); // Rotate screen by 270° #endif - - #if ENABLED(SHOW_BOOTSCREEN) - #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) - lcd_custom_bootscreen(); - #else - lcd_bootscreen(); - #endif - #endif } // The kill screen is displayed for unrecoverable conditions void lcd_kill_screen() { - lcd_setFont(FONT_MENU); - u8g.setPrintPos(0, u8g.getHeight()/4*1); - lcd_print_utf(lcd_status_message); - u8g.setPrintPos(0, u8g.getHeight()/4*2); - lcd_printPGM(PSTR(MSG_HALTED)); - u8g.setPrintPos(0, u8g.getHeight()/4*3); - lcd_printPGM(PSTR(MSG_PLEASE_RESET)); + u8g.firstPage(); + do { + lcd_setFont(FONT_MENU); + u8g.setPrintPos(0, u8g.getHeight()/4*1); + lcd_print_utf(lcd_status_message); + u8g.setPrintPos(0, u8g.getHeight()/4*2); + lcd_printPGM(PSTR(MSG_HALTED)); + u8g.setPrintPos(0, u8g.getHeight()/4*3); + lcd_printPGM(PSTR(MSG_PLEASE_RESET)); + } while (u8g.nextPage()); } void lcd_implementation_clear() { } // Automatically cleared by Picture Loop @@ -474,6 +476,7 @@ inline void lcd_implementation_status_message(const bool blink) { } } #else + UNUSED(blink); lcd_print_utf(lcd_status_message); #endif } @@ -493,7 +496,7 @@ static void lcd_implementation_status_screen() { if (PAGE_UNDER(STATUS_SCREENHEIGHT + 1)) { - u8g.drawBitmapP(9, 1, STATUS_SCREENBYTEWIDTH, STATUS_SCREENHEIGHT, + u8g.drawBitmapP(9, 1, (STATUS_SCREENWIDTH + 7) / 8, STATUS_SCREENHEIGHT, #if HAS_FAN0 blink && fanSpeeds[0] ? status_screen0_bmp : status_screen1_bmp #else @@ -535,7 +538,7 @@ static void lcd_implementation_status_screen() { // SD Card Symbol // - if (PAGE_CONTAINS(42 - (TALL_FONT_CORRECTION), 51 - (TALL_FONT_CORRECTION))) { + if (card.isFileOpen() && PAGE_CONTAINS(42 - (TALL_FONT_CORRECTION), 51 - (TALL_FONT_CORRECTION))) { // Upper box u8g.drawBox(42, 42 - (TALL_FONT_CORRECTION), 8, 7); // 42-48 (or 41-47) // Right edge @@ -559,7 +562,11 @@ static void lcd_implementation_status_screen() { PROGRESS_BAR_WIDTH, 4 - (TALL_FONT_CORRECTION) ); - if (IS_SD_PRINTING) { + #if DISABLED(LCD_SET_PROGRESS_MANUALLY) + const uint8_t progress_bar_percent = card.percentDone(); + #endif + + if (progress_bar_percent > 1) { // // Progress bar solid part @@ -568,7 +575,7 @@ static void lcd_implementation_status_screen() { if (PAGE_CONTAINS(50, 51 - (TALL_FONT_CORRECTION))) // 50-51 (or just 50) u8g.drawBox( PROGRESS_BAR_X + 1, 50, - (uint16_t)((PROGRESS_BAR_WIDTH - 2) * card.percentDone() * 0.01), 2 - (TALL_FONT_CORRECTION) + (uint16_t)((PROGRESS_BAR_WIDTH - 2) * progress_bar_percent * 0.01), 2 - (TALL_FONT_CORRECTION) ); // @@ -579,7 +586,7 @@ static void lcd_implementation_status_screen() { if (PAGE_CONTAINS(41, 48)) { // Percent complete u8g.setPrintPos(55, 48); - u8g.print(itostr3(card.percentDone())); + u8g.print(itostr3(progress_bar_percent)); u8g.print('%'); } #endif @@ -642,12 +649,17 @@ static void lcd_implementation_status_screen() { // At the first page, regenerate the XYZ strings if (page.page == 0) { - strcpy(xstring, ftostr4sign(current_position[X_AXIS])); - strcpy(ystring, ftostr4sign(current_position[Y_AXIS])); - strcpy(zstring, ftostr52sp(FIXFLOAT(current_position[Z_AXIS]))); - #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) + strcpy(xstring, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS]))); + strcpy(ystring, ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS]))); + strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS])))); + #if ENABLED(FILAMENT_LCD_DISPLAY) strcpy(wstring, ftostr12ns(filament_width_meas)); - strcpy(mstring, itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + strcpy(mstring, itostr3(100.0 * ( + parser.volumetric_enabled + ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + ) + )); #endif } @@ -703,7 +715,7 @@ static void lcd_implementation_status_screen() { // // Filament sensor display if SD is disabled // - #if DISABLED(SDSUPPORT) && ENABLED(FILAMENT_LCD_DISPLAY) + #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) u8g.setPrintPos(56, 50); lcd_print(wstring); u8g.setPrintPos(102, 50); @@ -733,10 +745,10 @@ static void lcd_implementation_status_screen() { else { lcd_printPGM(PSTR(LCD_STR_FILAM_DIA)); u8g.print(':'); - lcd_print(ftostr12ns(filament_width_meas)); + lcd_print(wstring); lcd_printPGM(PSTR(" " LCD_STR_FILAM_MUL)); u8g.print(':'); - lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd_print(mstring); u8g.print('%'); } #else @@ -930,19 +942,36 @@ static void lcd_implementation_status_screen() { if (!PAGE_CONTAINS(row_y1, row_y2)) return; - uint8_t n = LCD_WIDTH - (START_COL) - 1; + constexpr uint8_t maxlen = LCD_WIDTH - (START_COL) - 1; + const char *outstr = longFilename[0] ? longFilename : filename; if (longFilename[0]) { - filename = longFilename; - longFilename[n] = '\0'; // cutoff at screen edge + #if ENABLED(SCROLL_LONG_FILENAMES) + if (isSelected) { + uint8_t name_hash = row; + for (uint8_t l = FILENAME_LENGTH; l--;) + name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ filename[l]; // rotate, xor + if (filename_scroll_hash != name_hash) { // If the hash changed... + filename_scroll_hash = name_hash; // Save the new hash + filename_scroll_max = max(0, lcd_strlen(longFilename) - maxlen); // Update the scroll limit + filename_scroll_pos = 0; // Reset scroll to the start + lcd_status_update_delay = 8; // Don't scroll right away + } + outstr += filename_scroll_pos; + } + #else + longFilename[maxlen] = '\0'; // cutoff at screen edge + #endif } if (isDir) lcd_print(LCD_STR_FOLDER[0]); - while (char c = *filename) { + char c; + uint8_t n = maxlen; + while (n && (c = *outstr)) { n -= lcd_print_and_count(c); - filename++; + ++outstr; } - while (n--) u8g.print(' '); + while (n) { --n; u8g.print(' '); } } #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false) diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h index 74429b4085..5a8fd5fad8 100644 --- a/Marlin/ultralcd_impl_HD44780.h +++ b/Marlin/ultralcd_impl_HD44780.h @@ -200,9 +200,9 @@ extern volatile uint8_t buttons; //an extended version of the last checked butt #include "utf_mapper.h" #if ENABLED(LCD_PROGRESS_BAR) - static millis_t progress_bar_ms = 0; + static millis_t progress_bar_ms = 0; // Start millis of the current progress bar cycle #if PROGRESS_MSG_EXPIRE > 0 - static millis_t expire_status_ms = 0; + static millis_t expire_status_ms = 0; // millis at which to expire the status message #endif #define LCD_STR_PROGRESS "\x03\x04\x05" #endif @@ -218,11 +218,57 @@ static void createChar_P(const char c, const byte * const ptr) { lcd.createChar(c, temp); } +#define CHARSET_MENU 0 +#define CHARSET_INFO 1 +#define CHARSET_BOOT 2 + static void lcd_set_custom_characters( - #if ENABLED(LCD_PROGRESS_BAR) - const bool info_screen_charset = true + #if ENABLED(LCD_PROGRESS_BAR) || ENABLED(SHOW_BOOTSCREEN) + const uint8_t screen_charset=CHARSET_INFO #endif ) { + // CHARSET_BOOT + #if ENABLED(SHOW_BOOTSCREEN) + const static PROGMEM byte corner[4][8] = { { + B00000, + B00000, + B00000, + B00000, + B00001, + B00010, + B00100, + B00100 + }, { + B00000, + B00000, + B00000, + B11100, + B11100, + B01100, + B00100, + B00100 + }, { + B00100, + B00010, + B00001, + B00000, + B00000, + B00000, + B00000, + B00000 + }, { + B00100, + B01000, + B10000, + B00000, + B00000, + B00000, + B00000, + B00000 + } }; + #endif // SHOW_BOOTSCREEN + + // CHARSET_INFO const static PROGMEM byte bedTemp[8] = { B00000, B11111, @@ -290,6 +336,8 @@ static void lcd_set_custom_characters( }; #if ENABLED(SDSUPPORT) + + // CHARSET_MENU const static PROGMEM byte refresh[8] = { B00000, B00110, @@ -312,6 +360,8 @@ static void lcd_set_custom_characters( }; #if ENABLED(LCD_PROGRESS_BAR) + + // CHARSET_INFO const static PROGMEM byte progress[3][8] = { { B00000, B10000, @@ -340,43 +390,61 @@ static void lcd_set_custom_characters( B10101, B00000 } }; - #endif - #endif - createChar_P(LCD_BEDTEMP_CHAR, bedTemp); - createChar_P(LCD_DEGREE_CHAR, degree); - createChar_P(LCD_STR_THERMOMETER[0], thermometer); - createChar_P(LCD_FEEDRATE_CHAR, feedrate); - createChar_P(LCD_CLOCK_CHAR, clock); + #endif // LCD_PROGRESS_BAR - #if ENABLED(SDSUPPORT) - #if ENABLED(LCD_PROGRESS_BAR) - static bool char_mode = false; - if (info_screen_charset != char_mode) { - char_mode = info_screen_charset; - if (info_screen_charset) { // Progress bar characters for info screen - for (int16_t i = 3; i--;) createChar_P(LCD_STR_PROGRESS[i], progress[i]); - } - else { // Custom characters for submenus - createChar_P(LCD_UPLEVEL_CHAR, uplevel); - createChar_P(LCD_STR_REFRESH[0], refresh); - createChar_P(LCD_STR_FOLDER[0], folder); - } - } - #else - createChar_P(LCD_UPLEVEL_CHAR, uplevel); - createChar_P(LCD_STR_REFRESH[0], refresh); - createChar_P(LCD_STR_FOLDER[0], folder); - #endif + #endif // SDSUPPORT + #if ENABLED(SHOW_BOOTSCREEN) || ENABLED(LCD_PROGRESS_BAR) + static uint8_t char_mode = CHARSET_MENU; + #define CHAR_COND (screen_charset != char_mode) #else - createChar_P(LCD_UPLEVEL_CHAR, uplevel); + #define CHAR_COND true #endif + + if (CHAR_COND) { + #if ENABLED(SHOW_BOOTSCREEN) || ENABLED(LCD_PROGRESS_BAR) + char_mode = screen_charset; + #if ENABLED(SHOW_BOOTSCREEN) + // Set boot screen corner characters + if (screen_charset == CHARSET_BOOT) { + for (uint8_t i = 4; i--;) + createChar_P(i, corner[i]); + } + else + #endif + #endif + { // Info Screen uses 5 special characters + createChar_P(LCD_BEDTEMP_CHAR, bedTemp); + createChar_P(LCD_DEGREE_CHAR, degree); + createChar_P(LCD_STR_THERMOMETER[0], thermometer); + createChar_P(LCD_FEEDRATE_CHAR, feedrate); + createChar_P(LCD_CLOCK_CHAR, clock); + + #if ENABLED(SDSUPPORT) + #if ENABLED(LCD_PROGRESS_BAR) + if (screen_charset == CHARSET_INFO) { // 3 Progress bar characters for info screen + for (int16_t i = 3; i--;) + createChar_P(LCD_STR_PROGRESS[i], progress[i]); + } + else + #endif + { // SD Card sub-menu special characters + createChar_P(LCD_UPLEVEL_CHAR, uplevel); + createChar_P(LCD_STR_REFRESH[0], refresh); + createChar_P(LCD_STR_FOLDER[0], folder); + } + #else + // With no SD support, only need the uplevel character + createChar_P(LCD_UPLEVEL_CHAR, uplevel); + #endif + } + } } static void lcd_implementation_init( #if ENABLED(LCD_PROGRESS_BAR) - const bool info_screen_charset = true + const uint8_t screen_charset=CHARSET_INFO #endif ) { @@ -406,7 +474,7 @@ static void lcd_implementation_init( lcd_set_custom_characters( #if ENABLED(LCD_PROGRESS_BAR) - info_screen_charset + screen_charset #endif ); @@ -458,46 +526,7 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { } void lcd_bootscreen() { - const static PROGMEM byte corner[4][8] = { { - B00000, - B00000, - B00000, - B00000, - B00001, - B00010, - B00100, - B00100 - }, { - B00000, - B00000, - B00000, - B11100, - B11100, - B01100, - B00100, - B00100 - }, { - B00100, - B00010, - B00001, - B00000, - B00000, - B00000, - B00000, - B00000 - }, { - B00100, - B01000, - B10000, - B00000, - B00000, - B00000, - B00000, - B00000 - } }; - for (uint8_t i = 0; i < 4; i++) - createChar_P(i, corner[i]); - + lcd_set_custom_characters(CHARSET_BOOT); lcd.clear(); #define LCD_EXTRA_SPACE (LCD_WIDTH-8) @@ -565,14 +594,9 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { #endif lcd.clear(); - safe_delay(100); - - lcd_set_custom_characters( - #if ENABLED(LCD_PROGRESS_BAR) - false - #endif - ); + lcd_set_custom_characters(); + lcd.clear(); } #endif // SHOW_BOOTSCREEN @@ -618,7 +642,9 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co lcd.print(itostr3(t1 + 0.5)); lcd.write('/'); - #if HEATER_IDLE_HANDLER + #if !HEATER_IDLE_HANDLER + UNUSED(blink); + #else const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) : #if HAS_TEMP_BED thermalManager.is_bed_idle() @@ -710,10 +736,10 @@ static void lcd_implementation_status_screen() { lcd.setCursor(8, 0); #if HOTENDS > 1 - lcd.print((CHAR)LCD_STR_THERMOMETER[0]); + lcd.print((char)LCD_STR_THERMOMETER[0]); _draw_heater_status(1, -1, blink); #else - lcd.print((CHAR)LCD_BEDTEMP_CHAR); + lcd.print((char)LCD_BEDTEMP_CHAR); _draw_heater_status(-1, -1, blink); #endif @@ -776,12 +802,12 @@ static void lcd_implementation_status_screen() { // When everything is ok you see a constant 'X'. _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); - lcd.print(ftostr4sign(current_position[X_AXIS])); + lcd.print(ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS]))); lcd.write(' '); _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); - lcd.print(ftostr4sign(current_position[Y_AXIS])); + lcd.print(ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS]))); #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 @@ -792,7 +818,7 @@ static void lcd_implementation_status_screen() { lcd.print(ftostr52sp(FIXFLOAT(current_position[Z_AXIS]))); #if HAS_LEVELING - lcd.write(leveling_is_active() || blink ? '_' : ' '); + lcd.write(planner.leveling_active || blink ? '_' : ' '); #endif #endif // LCD_HEIGHT > 2 @@ -841,10 +867,11 @@ static void lcd_implementation_status_screen() { // Draw the progress bar if the message has shown long enough // or if there is no message set. - if (card.isFileOpen() && (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !lcd_status_message[0])) { - const uint8_t percent = card.percentDone(); - if (percent) return lcd_draw_progress_bar(percent); - } + #if DISABLED(LCD_SET_PROGRESS_MANUALLY) + const uint8_t progress_bar_percent = card.percentDone(); + #endif + if (progress_bar_percent > 2 && (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !lcd_status_message[0])) + return lcd_draw_progress_bar(progress_bar_percent); #elif ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) @@ -854,7 +881,12 @@ static void lcd_implementation_status_screen() { lcd_printPGM(PSTR("Dia ")); lcd.print(ftostr12ns(filament_width_meas)); lcd_printPGM(PSTR(" V")); - lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd.print(itostr3(100.0 * ( + parser.volumetric_enabled + ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + : planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] + ) + )); lcd.write('%'); return; } @@ -987,18 +1019,37 @@ static void lcd_implementation_status_screen() { static void lcd_implementation_drawmenu_sd(const bool sel, const uint8_t row, const char* const pstr, const char* filename, char* const longFilename, const uint8_t concat, const char post_char) { UNUSED(pstr); - uint8_t n = LCD_WIDTH - concat; lcd.setCursor(0, row); lcd.print(sel ? '>' : ' '); + + uint8_t n = LCD_WIDTH - concat; + const char *outstr = longFilename[0] ? longFilename : filename; if (longFilename[0]) { - filename = longFilename; - longFilename[n] = '\0'; + #if ENABLED(SCROLL_LONG_FILENAMES) + if (sel) { + uint8_t name_hash = row; + for (uint8_t l = FILENAME_LENGTH; l--;) + name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ filename[l]; // rotate, xor + if (filename_scroll_hash != name_hash) { // If the hash changed... + filename_scroll_hash = name_hash; // Save the new hash + filename_scroll_max = max(0, lcd_strlen(longFilename) - n); // Update the scroll limit + filename_scroll_pos = 0; // Reset scroll to the start + lcd_status_update_delay = 8; // Don't scroll right away + } + outstr += filename_scroll_pos; + } + #else + longFilename[n] = '\0'; // cutoff at screen edge + #endif } - while (char c = *filename) { + + char c; + while (n && (c = *outstr)) { n -= charset_mapper(c); - filename++; + ++outstr; } - while (n--) lcd.write(' '); + while (n) { --n; lcd.write(' '); } + lcd.print(post_char); } @@ -1145,9 +1196,9 @@ static void lcd_implementation_status_screen() { return ret_val; } - coordinate pixel_location(uint8_t x, uint8_t y) { return pixel_location((int16_t)x, (int16_t)y); } + inline coordinate pixel_location(const uint8_t x, const uint8_t y) { return pixel_location((int16_t)x, (int16_t)y); } - void lcd_implementation_ubl_plot(uint8_t x, uint8_t inverted_y) { + void lcd_implementation_ubl_plot(const uint8_t x, const uint8_t inverted_y) { #if LCD_WIDTH >= 20 #define _LCD_W_POS 12 diff --git a/Marlin/ultralcd_st7565_u8glib_VIKI.h b/Marlin/ultralcd_st7565_u8glib_VIKI.h index b7bb2e26c1..2121b70de4 100644 --- a/Marlin/ultralcd_st7565_u8glib_VIKI.h +++ b/Marlin/ultralcd_st7565_u8glib_VIKI.h @@ -52,15 +52,15 @@ #define CPU_ST7565_DELAY_1 DELAY_0_NOP #define CPU_ST7565_DELAY_2 DELAY_0_NOP #define CPU_ST7565_DELAY_3 DELAY_1_NOP -#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) +#elif MB(3DRAG) || MB(K8200) || MB(K8400) #define CPU_ST7565_DELAY_1 DELAY_0_NOP #define CPU_ST7565_DELAY_2 DELAY_3_NOP #define CPU_ST7565_DELAY_3 DELAY_0_NOP -#elif (MOTHERBOARD == BOARD_MINIRAMBO) +#elif MB(MINIRAMBO) #define CPU_ST7565_DELAY_1 DELAY_0_NOP #define CPU_ST7565_DELAY_2 DELAY_4_NOP #define CPU_ST7565_DELAY_3 DELAY_0_NOP -#elif (MOTHERBOARD == BOARD_RAMBO) +#elif MB(RAMBO) #define CPU_ST7565_DELAY_1 DELAY_0_NOP #define CPU_ST7565_DELAY_2 DELAY_0_NOP #define CPU_ST7565_DELAY_3 DELAY_0_NOP diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h index 150b850d46..67de4611e7 100644 --- a/Marlin/ultralcd_st7920_u8glib_rrd.h +++ b/Marlin/ultralcd_st7920_u8glib_rrd.h @@ -48,15 +48,15 @@ #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_0_NOP #define CPU_ST7920_DELAY_3 DELAY_1_NOP -#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) +#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_3_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP -#elif (MOTHERBOARD == BOARD_MINIRAMBO) +#elif MB(MINIRAMBO) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_4_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP -#elif (MOTHERBOARD == BOARD_RAMBO) +#elif MB(RAMBO) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_0_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP diff --git a/Marlin/watchdog.cpp b/Marlin/watchdog.cpp index 5e42b5faca..135a050fff 100644 --- a/Marlin/watchdog.cpp +++ b/Marlin/watchdog.cpp @@ -26,17 +26,28 @@ #include "watchdog.h" -// Initialize watchdog with a 4 sec interrupt time +// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s. void watchdog_init() { + #if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S) + #define WDTO_NS WDTO_8S + #else + #define WDTO_NS WDTO_4S + #endif #if ENABLED(WATCHDOG_RESET_MANUAL) // We enable the watchdog timer, but only for the interrupt. - // Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details. + // Take care, as this requires the correct order of operation, with interrupts disabled. + // See the datasheet of any AVR chip for details. wdt_reset(); + cli(); _WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE); - _WD_CONTROL_REG = _BV(WDIE) | WDTO_4S; + _WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5 + // So worked for up to WDTO_2S + sei(); + wdt_reset(); #else - wdt_enable(WDTO_4S); + wdt_enable(WDTO_NS); // The function handles the upper bit correct. #endif + //delay(10000); // test it! } //=========================================================================== @@ -46,9 +57,10 @@ void watchdog_init() { // Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled. #if ENABLED(WATCHDOG_RESET_MANUAL) ISR(WDT_vect) { + sei(); // With the interrupt driven serial we need to allow interrupts. SERIAL_ERROR_START(); - SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer."); - kill(PSTR("ERR:Please Reset")); //kill blocks //16 characters so it fits on a 16x2 display + SERIAL_ERRORLNPGM("Watchdog barked, please turn off the printer."); + kill(PSTR("ERR:Watchdog")); //kill blocks //up to 16 characters so it fits on a 16x2 display while (1); //wait for user or serial reset } #endif // WATCHDOG_RESET_MANUAL diff --git a/README.md b/README.md index af5d9732fa..0aba664619 100644 --- a/README.md +++ b/README.md @@ -44,37 +44,42 @@ Arduino IDE now has support for folder hierarchies, so Marlin 1.2 will have a [h ## Credits The current Marlin dev team consists of: - - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - English - - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - English - - Bob Kuhn [[@Bob-the-Kuhn](https://github.com/Bob-the-Kuhn)] - English - - Andreas Hardtung [[@AnHardt](https://github.com/AnHardt)] - Deutsch, English - - Nico Tonnhofer [[@Wurstnase](https://github.com/Wurstnase)] - Deutsch, English - - Jochen Groppe [[@CONSULitAS](https://github.com/CONSULitAS)] - Deutsch, English - - João Brazio [[@jbrazio](https://github.com/jbrazio)] - Portuguese, English - - Bo Hermannsen [[@boelle](https://github.com/boelle)] - Danish, English - - Bob Cousins [[@bobc](https://github.com/bobc)] - English - - [[@maverikou](https://github.com/maverikou)] - - Chris Palmer [[@nophead](https://github.com/nophead)] - - [[@paclema](https://github.com/paclema)] - - Erik van der Zalm [[@ErikZalm](https://github.com/ErikZalm)] - - David Braam [[@daid](https://github.com/daid)] - - Bernhard Kubicek [[@bkubicek](https://github.com/bkubicek)] + - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] + - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] + - Bob Kuhn [[@Bob-the-Kuhn](https://github.com/Bob-the-Kuhn)] -More features have been added by: - - Alberto Cotronei [[@MagoKimbra](https://github.com/MagoKimbra)] - English, Italian - - Thomas Moore [[@tcm0116](https://github.com/tcm0116)] - - Ernesto Martinez [[@emartinez167](https://github.com/emartinez167)] - - Petr Zahradnik [[@clexpert](https://github.com/clexpert)] - - Kai [[@Kaibob2](https://github.com/Kaibob2)] +Notable contributors include: + - Alberto Cotronei [[@MagoKimbra](https://github.com/MagoKimbra)] + - Andreas Hardtung [[@AnHardt](https://github.com/AnHardt)] + - Bernhard Kubicek [[@bkubicek](https://github.com/bkubicek)] + - Bob Cousins [[@bobc](https://github.com/bobc)] + - Chris Palmer [[@nophead](https://github.com/nophead)] + - David Braam [[@daid](https://github.com/daid)] - Edward Patel [[@epatel](https://github.com/epatel)] - - F. Malpartida [[@fmalpartida](https://github.com/fmalpartida)] - English, Spanish - - [[@esenapaj](https://github.com/esenapaj)] - English, Japanese + - Erik van der Zalm [[@ErikZalm](https://github.com/ErikZalm)] + - Ernesto Martinez [[@emartinez167](https://github.com/emartinez167)] + - F. Malpartida [[@fmalpartida](https://github.com/fmalpartida)] + - Jochen Groppe [[@CONSULitAS](https://github.com/CONSULitAS)] + - João Brazio [[@jbrazio](https://github.com/jbrazio)] + - Kai [[@Kaibob2](https://github.com/Kaibob2)] + - Luc Van Daele[[@LVD-AC](https://github.com/LVD-AC)] + - Nico Tonnhofer [[@Wurstnase](https://github.com/Wurstnase)] + - Petr Zahradnik [[@clexpert](https://github.com/clexpert)] + - Thomas Moore [[@tcm0116](https://github.com/tcm0116)] + - [[@alexxy](https://github.com/alexxy)] + - [[@android444](https://github.com/android444)] - [[@benlye](https://github.com/benlye)] + - [[@bgort](https://github.com/bgort)] + - [[@Grogyan](https://github.com/Grogyan)] + - [[@marcio-ao](https://github.com/marcio-ao)] + - [[@maverikou](https://github.com/maverikou)] + - [[@oysteinkrog](https://github.com/oysteinkrog)] + - [[@p3p](https://github.com/p3p)] + - [[@paclema](https://github.com/paclema)] + - [[@paulusjacobus](https://github.com/paulusjacobus)] + - [[@psavva](https://github.com/psavva)] - [[@Tannoo](https://github.com/Tannoo)] - [[@teemuatlut](https://github.com/teemuatlut)] - - [[@bgort](https://github.com/bgort)] - - Luc Van Daele[[@LVD-AC](https://github.com/LVD-AC)] - Dutch, French, English - - [[@paulusjacobus](https://github.com/paulusjacobus)] - ...and many others ## License diff --git a/buildroot/bin/opt_add b/buildroot/bin/opt_add new file mode 100755 index 0000000000..8361cac527 --- /dev/null +++ b/buildroot/bin/opt_add @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +eval "echo \"#define ${1} ${2}\" >>Marlin/Configuration.h" diff --git a/buildroot/bin/opt_add_adv b/buildroot/bin/opt_add_adv new file mode 100755 index 0000000000..8ef7e07917 --- /dev/null +++ b/buildroot/bin/opt_add_adv @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +eval "echo \"#define ${1} ${2}\" >>Marlin/Configuration_adv.h" diff --git a/buildroot/bin/use_example_configs b/buildroot/bin/use_example_configs index 9f55c52e1f..21031ee121 100755 --- a/buildroot/bin/use_example_configs +++ b/buildroot/bin/use_example_configs @@ -1,7 +1,9 @@ #!/usr/bin/env bash -eval "cp Marlin/example_configurations/${1}/Configuration* Marlin/" +restore_configs -if [ -f "Marlin/example_configurations/${1}/_Bootscreen.h" ]; then - cp "Marlin/example_configurations/${1}/_Bootscreen.h" Marlin/ +cp Marlin/example_configurations/"$@"/Configuration* Marlin/ + +if [ -f "Marlin/example_configurations/$@/_Bootscreen.h" ]; then + cp "Marlin/example_configurations/$@/_Bootscreen.h" Marlin/ fi diff --git a/buildroot/share/git/mfinfo b/buildroot/share/git/mfinfo index febbcc3ecf..51b1e86995 100755 --- a/buildroot/share/git/mfinfo +++ b/buildroot/share/git/mfinfo @@ -7,11 +7,15 @@ # - Remote (upstream) Org name (MarlinFirmware) # - Remote (origin) Org name (your Github username) # - Repo Name (Marlin, MarlinDev, MarlinDocumentation) -# - PR Target branch (bugfix-1.1.x, dev, or master) +# - PR Target branch (bugfix-1.1.x, bugfix-2.0.x, or master) # - Branch Arg (the branch argument or current branch) # - Current Branch # +usage() { + echo "Usage: `basename $0` [1|2] [branch]" 1>&2 +} + CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g') [[ -z $CURR ]] && { echo "No git repository here!" 1>&2 ; exit 1; } [[ $CURR == "(no"* ]] && { echo "Git is busy with merge, rebase, etc." 1>&2 ; exit 1; } @@ -23,17 +27,29 @@ ORG=$(git remote get-url upstream 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/') [[ $ORG == MarlinFirmware ]] || { echo "`basename $0`: Not a Marlin repository." 1>&2 ; exit 1; } case "$REPO" in - Marlin ) TARG=bugfix-1.1.x ;; - MarlinDev ) TARG=dev ;; + Marlin ) TARG=bugfix-1.1.x ; + [[ $# > 0 ]] && [[ $1 == 2 ]] && TARG=bugfix-2.0.x + ;; MarlinDocumentation ) TARG=master ;; esac FORK=$(git remote get-url origin 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/') +# BRANCH can be given as the last argument case "$#" in 0 ) BRANCH=$CURR ;; - 1 ) BRANCH=$1 ;; - * ) echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1 ;; + 1 ) + case "$1" in + 1|2) BRANCH=$CURR ;; + *) BRANCH=$1 ;; + esac + ;; + 2 ) + case "$1" in + 1|2) BRANCH=$2 ;; + *) usage ; exit 1 ;; + esac + ;; esac echo "$ORG $FORK $REPO $TARG $BRANCH $CURR" diff --git a/buildroot/share/git/mfnew b/buildroot/share/git/mfnew index f1e495cbc4..622622734b 100755 --- a/buildroot/share/git/mfnew +++ b/buildroot/share/git/mfnew @@ -5,15 +5,29 @@ # Create a new branch from the default target with the given name # -[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } +usage() { + echo "Usage: `basename $0` [1|2] [name]" 1>&2 +} -MFINFO=$(mfinfo) || exit 1 +[[ $# < 3 ]] || { usage ; exit 1 ; } + +MFINFO=$(mfinfo "$@") || exit 1 IFS=' ' read -a INFO <<< "$MFINFO" TARG=${INFO[3]} +BRANCH=pr_for_$TARG-$(date +"%G-%m-%d_%H.%M.%S") +# BRANCH can be given as the last argument case "$#" in - 0 ) BRANCH=pr_for_$TARG-$(date +"%G-%m-%d_%H.%M.%S") ;; - 1 ) BRANCH=$1 ;; + 1 ) case "$1" in + 1|2) ;; + *) BRANCH=$1 ;; + esac + ;; + 2 ) case "$1" in + 1|2) BRANCH=$2 ;; + *) usage ; exit 1 ;; + esac + ;; esac git fetch upstream diff --git a/buildroot/share/git/mfpub b/buildroot/share/git/mfpub index 9b48480d0e..9a3e1caa6f 100755 --- a/buildroot/share/git/mfpub +++ b/buildroot/share/git/mfpub @@ -35,7 +35,7 @@ fi echo "Stashing any changes to files..." echo "Don't forget to update and push 'master'!" # GOJF Card -git stash +[[ $(git stash) != "No local "* ]] && HAS_STASH=1 COMMIT=$( git log --format="%H" -n 1 ) @@ -45,14 +45,27 @@ git clean -d -f # Push 'master' to the fork and make a proper PR... if [[ $BRANCH == "master" ]]; then - # Allow working directly with the main fork - echo - echo -n "Pushing to origin/master... " - git push -f origin + # Don't lose upstream changes! + git fetch upstream - echo - echo -n "Pushing to upstream/master... " - git push -f upstream + # Rebase onto latest master + if git rebase upstream/master; then + + # Allow working directly with the main fork + echo + echo -n "Pushing to origin/master... " + git push -f origin + + echo + echo -n "Pushing to upstream/master... " + git push -f upstream + + else + + echo "Merge conflicts? Stopping here." + exit + + fi else @@ -111,6 +124,4 @@ rm -rf ${TMPFOLDER} # Go back to the branch we started from git checkout $BRANCH -if [[ $BRANCH != "master" ]]; then - git stash pop -fi +[[ $HAS_STASH == 1 ]] && git stash pop diff --git a/buildroot/share/git/mfqp b/buildroot/share/git/mfqp index 97cac5dbef..5a91a8af92 100755 --- a/buildroot/share/git/mfqp +++ b/buildroot/share/git/mfqp @@ -5,24 +5,23 @@ # Add all changed files, commit as "patch", do `mfrb` and `git push -f` # -[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } +[[ $# < 2 ]] || { echo "Usage: `basename $0` [1|2]" 1>&2 ; exit 1; } -MFINFO=$(mfinfo) || exit 1 +MFINFO=$(mfinfo "$@") || exit 1 IFS=' ' read -a INFO <<< "$MFINFO" REPO=${INFO[2]} TARG=${INFO[3]} -BRANCH=${INFO[5]} +CURR=${INFO[5]} git add . git commit -m "patch" -if [[ $BRANCH == $TARG ]]; then +if [[ $CURR == $TARG ]]; then if [[ $REPO == "MarlinDocumentation" ]]; then - git rebase -i HEAD~2 + git rebase -i HEAD~2 && git push -f else echo "Don't alter the PR Target branch."; exit 1 fi else - mfrb - git push -f + mfrb "$@" && git push -f fi diff --git a/buildroot/share/git/mfrb b/buildroot/share/git/mfrb index b376b40746..af4de26dc4 100755 --- a/buildroot/share/git/mfrb +++ b/buildroot/share/git/mfrb @@ -2,18 +2,18 @@ # # mfrb # -# Do "git rebase -i" against the "target" branch (RCBugFix or dev) +# Do "git rebase -i" against the "target" branch (bugfix-1.1.x, bugfix-2.0.x, or master) # -[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } +[[ $# < 2 ]] || { echo "Usage: `basename $0` [1|2]" 1>&2 ; exit 1; } -MFINFO=$(mfinfo) || exit 1 +MFINFO=$(mfinfo "$@") || exit 1 IFS=' ' read -a INFO <<< "$MFINFO" TARG=${INFO[3]} -BRANCH=${INFO[5]} +CURR=${INFO[5]} # If the branch isn't currently the PR target -if [[ $TARG != $BRANCH ]]; then +if [[ $TARG != $CURR ]]; then git fetch upstream git rebase upstream/$TARG && git rebase -i upstream/$TARG fi diff --git a/buildroot/share/git/mfup b/buildroot/share/git/mfup index df2da87b2c..132c36b3b4 100755 --- a/buildroot/share/git/mfup +++ b/buildroot/share/git/mfup @@ -5,10 +5,9 @@ # - Fetch latest upstream and replace the PR Target branch with # - Rebase the (current or specified) branch on the PR Target # - Force-push the branch to 'origin' -# - # -[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } +[[ $# < 3 ]] || { echo "Usage: `basename $0` [1|2] [branch]" 1>&2 ; exit 1; } MFINFO=$(mfinfo "$@") || exit 1 IFS=' ' read -a INFO <<< "$MFINFO" @@ -17,7 +16,7 @@ FORK=${INFO[1]} REPO=${INFO[2]} TARG=${INFO[3]} BRANCH=${INFO[4]} -OLDBRANCH=${INFO[5]} +CURR=${INFO[5]} set -e @@ -27,30 +26,23 @@ set -e echo "Fetching upstream ($ORG/$REPO)..." git fetch upstream -echo ; echo "Bringing $TARG up to date..." -if [[ ! $(git checkout -q $TARG) ]]; then - git reset --hard upstream/$TARG - git push -f origin -else - git checkout upstream/$TARG -b $TARG - git push --set-upstream origin $TARG -fi - if [[ $BRANCH != $TARG ]]; then echo ; echo "Rebasing $BRANCH on $TARG..." - if git checkout $BRANCH; then - echo - if git rebase $TARG; then + if [[ $BRANCH == $CURR ]] || git checkout $BRANCH; then + if git rebase upstream/$TARG; then git push -f else - echo "Looks like merge conflicts. Stopping here." ; exit + echo "Looks like merge conflicts. Stopping here." + exit fi else echo "No such branch!" fi +else + git reset --hard upstream/$TARG fi echo -[[ $BRANCH != $OLDBRANCH ]] && git checkout $OLDBRANCH +[[ $BRANCH != $CURR ]] && git checkout $CURR [[ $HAS_STASH == 1 ]] && git stash pop diff --git a/buildroot/share/scripts/createTemperatureLookupMarlin.py b/buildroot/share/scripts/createTemperatureLookupMarlin.py index 9859caaaa2..83147c502b 100755 --- a/buildroot/share/scripts/createTemperatureLookupMarlin.py +++ b/buildroot/share/scripts/createTemperatureLookupMarlin.py @@ -7,7 +7,7 @@ http://en.wikipedia.org/wiki/Steinhart-Hart_equation The main use is for Arduino programs that read data from the circuit board described here: http://reprap.org/wiki/Temperature_Sensor_v2.0 -Usage: python createTemperatureLookup.py [options] +Usage: python createTemperatureLookupMarlin.py [options] Options: -h, --help show this help @@ -134,14 +134,13 @@ def main(argv): print "// Thermistor lookup table for Marlin" print "// ./createTemperatureLookupMarlin.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps) print "// Steinhart-Hart Coefficients: a=%.15g, b=%.15g, c=%.15g " % (t.c1, t.c2, t.c3) - print "// Theoretical limits of termistor: %.2f to %.2f degC" % (low_bound, up_bound) + print "// Theoretical limits of thermistor: %.2f to %.2f degC" % (low_bound, up_bound) print - print "#define NUMTEMPS %s" % (len(temps)) - print "const short temptable[NUMTEMPS][2] PROGMEM = {" + print "const short temptable[][2] PROGMEM = {" for temp in temps: adc = t.adc(temp) - print " { (short) (%7.2f * OVERSAMPLENR ), %4s }%s // v=%.3f\tr=%.3f\tres=%.3f degC/count" % (adc , temp, \ + print " { OV(%7.2f), %4s }%s // v=%.3f\tr=%.3f\tres=%.3f degC/count" % (adc , temp, \ ',' if temp != temps[-1] else ' ', \ t.voltage(adc), \ t.resist( adc), \ diff --git a/platformio.ini b/platformio.ini index 3d7cff483e..dbd90e5a0b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -5,8 +5,10 @@ # http://docs.platformio.org/en/latest/projectconf.html # -# A sign `#` at the beginning of the line indicates a comment -# Comment lines are ignored. +# +# By default platformio build will abort after 5 errors. +# Remove '-fmax-errors=5' from build_flags below to see all. +# # Automatic targets - enable auto-uploading # targets = upload @@ -19,13 +21,19 @@ libdeps_dir = .piolibdeps env_default = megaatmega2560 [common] -lib_deps = U8glib@1.19.1 +lib_deps = + U8glib@1.19.1 + TMC2130Stepper + Adafruit NeoPixel + https://github.com/lincomatic/LiquidTWI2.git + https://github.com/trinamic/TMC26XStepper.git +build_flags = -I $BUILDSRC_DIR -fmax-errors=5 [env:megaatmega2560] platform = atmelavr framework = arduino board = megaatmega2560 -build_flags = -I $BUILDSRC_DIR +build_flags = ${common.build_flags} board_f_cpu = 16000000L lib_deps = ${common.lib_deps} @@ -33,7 +41,7 @@ lib_deps = ${common.lib_deps} platform = atmelavr framework = arduino board = megaatmega1280 -build_flags = -I $BUILDSRC_DIR +build_flags = ${common.build_flags} board_f_cpu = 16000000L lib_deps = ${common.lib_deps} @@ -41,7 +49,7 @@ lib_deps = ${common.lib_deps} platform = teensy framework = arduino board = teensy20pp -build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_PRINTRBOARD +build_flags = ${common.build_flags} -D MOTHERBOARD=BOARD_PRINTRBOARD # Bug in arduino framework does not allow boards running at 20Mhz #board_f_cpu = 20000000L lib_deps = ${common.lib_deps} @@ -50,21 +58,21 @@ lib_deps = ${common.lib_deps} platform = teensy framework = arduino board = teensy20pp -build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_PRINTRBOARD_REVF +build_flags = ${common.build_flags} -D MOTHERBOARD=BOARD_PRINTRBOARD_REVF lib_deps = ${common.lib_deps} [env:brainwavepro] platform = teensy framework = arduino board = teensy20pp -build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_BRAINWAVE_PRO +build_flags = ${common.build_flags} -D MOTHERBOARD=BOARD_BRAINWAVE_PRO lib_deps = ${common.lib_deps} [env:rambo] platform = atmelavr framework = arduino board = reprap_rambo -build_flags = -I $BUILDSRC_DIR +build_flags = ${common.build_flags} board_f_cpu = 16000000L lib_deps = ${common.lib_deps} @@ -72,6 +80,7 @@ lib_deps = ${common.lib_deps} platform = atmelavr framework = arduino board = sanguino_atmega1284p +build_flags = ${common.build_flags} upload_speed = 57600 lib_deps = ${common.lib_deps} @@ -79,4 +88,5 @@ lib_deps = ${common.lib_deps} platform = atmelavr framework = arduino board = sanguino_atmega644p +build_flags = ${common.build_flags} lib_deps = ${common.lib_deps}