From 584c86bed1d81548da03681bd3b3c6bd54ae0fe3 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 10 Sep 2019 02:20:49 -0500 Subject: [PATCH] More "zero extruders" changes (#15213) --- Marlin/src/feature/power_loss_recovery.cpp | 38 +- Marlin/src/feature/power_loss_recovery.h | 4 +- Marlin/src/gcode/config/M221.cpp | 4 + Marlin/src/gcode/gcode.cpp | 31 +- Marlin/src/gcode/gcode.h | 23 +- Marlin/src/gcode/lcd/M145.cpp | 4 +- Marlin/src/gcode/temperature/M104_M109.cpp | 6 + Marlin/src/inc/Conditionals_adv.h | 28 + Marlin/src/inc/Conditionals_post.h | 14 +- Marlin/src/inc/SanityCheck.h | 4 +- Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp | 12 +- Marlin/src/lcd/dogm/dogm_Statusscreen.h | 219 +++--- Marlin/src/lcd/dogm/status_screen_DOGM.cpp | 16 +- .../extensible_ui/lib/dgus/DGUSDisplay.cpp | 32 +- Marlin/src/lcd/extensible_ui/ui_api.cpp | 37 +- Marlin/src/lcd/menu/menu.h | 4 +- Marlin/src/lcd/menu/menu_advanced.cpp | 10 +- Marlin/src/lcd/menu/menu_motion.cpp | 244 +++--- Marlin/src/lcd/menu/menu_temperature.cpp | 18 +- Marlin/src/lcd/menu/menu_tune.cpp | 2 +- Marlin/src/module/configuration_store.cpp | 18 +- Marlin/src/module/motion.h | 4 +- Marlin/src/module/planner.cpp | 263 ++++--- Marlin/src/module/planner.h | 23 +- Marlin/src/module/temperature.cpp | 711 +++++++++--------- Marlin/src/module/temperature.h | 123 +-- Marlin/src/module/tool_change.cpp | 17 +- 27 files changed, 1068 insertions(+), 841 deletions(-) diff --git a/Marlin/src/feature/power_loss_recovery.cpp b/Marlin/src/feature/power_loss_recovery.cpp index 1c38e4f97..eb25bd427 100644 --- a/Marlin/src/feature/power_loss_recovery.cpp +++ b/Marlin/src/feature/power_loss_recovery.cpp @@ -175,7 +175,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*= info.active_extruder = active_extruder; #endif - HOTEND_LOOP() info.target_temperature[e] = thermalManager.temp_hotend[e].target; + #if EXTRUDERS + HOTEND_LOOP() info.target_temperature[e] = thermalManager.temp_hotend[e].target; + #endif #if HAS_HEATED_BED info.target_temperature_bed = thermalManager.temp_bed.target; @@ -297,17 +299,19 @@ void PrintJobRecovery::resume() { #endif // Restore all hotend temperatures - HOTEND_LOOP() { - const int16_t et = info.target_temperature[e]; - if (et) { - #if HOTENDS > 1 - sprintf_P(cmd, PSTR("T%i"), e); + #if HOTENDS + HOTEND_LOOP() { + const int16_t et = info.target_temperature[e]; + if (et) { + #if HOTENDS > 1 + sprintf_P(cmd, PSTR("T%i"), e); + gcode.process_subcommands_now(cmd); + #endif + sprintf_P(cmd, PSTR("M109 S%i"), et); gcode.process_subcommands_now(cmd); - #endif - sprintf_P(cmd, PSTR("M109 S%i"), et); - gcode.process_subcommands_now(cmd); + } } - } + #endif // Restore print cooling fan speeds FANS_LOOP(i) { @@ -452,12 +456,14 @@ void PrintJobRecovery::resume() { DEBUG_ECHOLNPAIR("active_extruder: ", int(info.active_extruder)); #endif - DEBUG_ECHOPGM("target_temperature: "); - HOTEND_LOOP() { - DEBUG_ECHO(info.target_temperature[e]); - if (e < HOTENDS - 1) DEBUG_CHAR(','); - } - DEBUG_EOL(); + #if HOTENDS + DEBUG_ECHOPGM("target_temperature: "); + HOTEND_LOOP() { + DEBUG_ECHO(info.target_temperature[e]); + if (e < HOTENDS - 1) DEBUG_CHAR(','); + } + DEBUG_EOL(); + #endif #if HAS_HEATED_BED DEBUG_ECHOLNPAIR("target_temperature_bed: ", info.target_temperature_bed); diff --git a/Marlin/src/feature/power_loss_recovery.h b/Marlin/src/feature/power_loss_recovery.h index 34322243f..2cfde0350 100644 --- a/Marlin/src/feature/power_loss_recovery.h +++ b/Marlin/src/feature/power_loss_recovery.h @@ -59,7 +59,9 @@ typedef struct { uint8_t active_extruder; #endif - int16_t target_temperature[HOTENDS]; + #if HOTENDS + int16_t target_temperature[HOTENDS]; + #endif #if HAS_HEATED_BED int16_t target_temperature_bed; diff --git a/Marlin/src/gcode/config/M221.cpp b/Marlin/src/gcode/config/M221.cpp index cbb31628a..116ce776b 100644 --- a/Marlin/src/gcode/config/M221.cpp +++ b/Marlin/src/gcode/config/M221.cpp @@ -23,6 +23,8 @@ #include "../gcode.h" #include "../../module/planner.h" +#if EXTRUDERS + /** * M221: Set extrusion percentage (M221 T0 S95) */ @@ -44,3 +46,5 @@ void GcodeSuite::M221() { SERIAL_EOL(); } } + +#endif // EXTRUDERS diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 8ad818c92..680fa3597 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -400,8 +400,18 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 100: M100(); break; // M100: Free Memory Report #endif - case 104: M104(); break; // M104: Set hot end temperature - case 109: M109(); break; // M109: Wait for hotend temperature to reach target + #if EXTRUDERS + case 104: M104(); break; // M104: Set hot end temperature + case 109: M109(); break; // M109: Wait for hotend temperature to reach target + #endif + + case 105: M105(); return; // M105: Report Temperatures (and say "ok") + + #if FAN_COUNT > 0 + case 106: M106(); break; // M106: Fan On + case 107: M107(); break; // M107: Fan Off + #endif + case 110: M110(); break; // M110: Set Current Line Number case 111: M111(); break; // M111: Set debug level @@ -410,7 +420,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 112: M112(); break; // M112: Full Shutdown case 410: M410(); break; // M410: Quickstop - Abort all the planned moves. #if ENABLED(HOST_PROMPT_SUPPORT) - case 876: M876(); break; // M876: Handle Host prompt responses + case 876: M876(); break; // M876: Handle Host prompt responses #endif #else case 108: case 112: case 410: @@ -434,17 +444,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { //case 191: M191(); break; // M191: Wait for chamber temperature to reach target #endif - case 105: M105(); return; // M105: Report Temperatures (and say "ok") - #if ENABLED(AUTO_REPORT_TEMPERATURES) && HAS_TEMP_SENSOR case 155: M155(); break; // M155: Set temperature auto-report interval #endif - #if FAN_COUNT > 0 - case 106: M106(); break; // M106: Fan On - case 107: M107(); break; // M107: Fan Off - #endif - #if ENABLED(PARK_HEAD_ON_PAUSE) case 125: M125(); break; // M125: Store current position and move to filament change position #endif @@ -481,7 +484,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 120: M120(); break; // M120: Enable endstops case 121: M121(); break; // M121: Disable endstops - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU case 145: M145(); break; // M145: Set material heatup parameters #endif @@ -553,7 +556,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif case 220: M220(); break; // M220: Set Feedrate Percentage: S ("FR" on your LCD) - case 221: M221(); break; // M221: Set Flow Percentage + + #if EXTRUDERS + case 221: M221(); break; // M221: Set Flow Percentage + #endif + case 226: M226(); break; // M226: Wait until a pin reaches a state #if HAS_SERVOS diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index c9b0cec2a..8840d40d6 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -543,10 +543,17 @@ private: static void M100(); #endif - static void M104(); + #if EXTRUDERS + static void M104(); + static void M109(); + #endif + static void M105(); - static void M106(); - static void M107(); + + #if FAN_COUNT > 0 + static void M106(); + static void M107(); + #endif #if DISABLED(EMERGENCY_PARSER) static void M108(); @@ -557,8 +564,6 @@ private: #endif #endif - static void M109(); - static void M110(); static void M111(); @@ -599,7 +604,7 @@ private: //static void M191(); #endif - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU static void M145(); #endif @@ -660,7 +665,11 @@ private: #endif static void M220(); - static void M221(); + + #if EXTRUDERS + static void M221(); + #endif + static void M226(); #if ENABLED(PHOTO_GCODE) diff --git a/Marlin/src/gcode/lcd/M145.cpp b/Marlin/src/gcode/lcd/M145.cpp index 693a32d24..297ece268 100644 --- a/Marlin/src/gcode/lcd/M145.cpp +++ b/Marlin/src/gcode/lcd/M145.cpp @@ -22,7 +22,7 @@ #include "../../inc/MarlinConfig.h" -#if HAS_LCD_MENU +#if HOTENDS && HAS_LCD_MENU #include "../gcode.h" #include "../../lcd/ultralcd.h" @@ -58,4 +58,4 @@ void GcodeSuite::M145() { } } -#endif // HAS_LCD_MENU +#endif // HOTENDS && HAS_LCD_MENU diff --git a/Marlin/src/gcode/temperature/M104_M109.cpp b/Marlin/src/gcode/temperature/M104_M109.cpp index f4259abff..86da46a89 100644 --- a/Marlin/src/gcode/temperature/M104_M109.cpp +++ b/Marlin/src/gcode/temperature/M104_M109.cpp @@ -20,6 +20,10 @@ * */ +#include "../../inc/MarlinConfigPre.h" + +#if EXTRUDERS + #include "../gcode.h" #include "../../module/temperature.h" #include "../../module/motion.h" @@ -138,3 +142,5 @@ void GcodeSuite::M109() { if (set_temp) (void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling); } + +#endif // EXTRUDERS diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 37ec8c09a..b9b885542 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -26,6 +26,34 @@ * Defines that depend on advanced configuration. */ +#if EXTRUDERS == 0 + #define NO_VOLUMETRICS + #undef TEMP_SENSOR_0 + #undef TEMP_SENSOR_1 + #undef TEMP_SENSOR_2 + #undef TEMP_SENSOR_3 + #undef TEMP_SENSOR_4 + #undef TEMP_SENSOR_5 + #undef FWRETRACT + #undef PIDTEMP + #undef AUTOTEMP + #undef PID_EXTRUSION_SCALING + #undef LIN_ADVANCE + #undef FILAMENT_RUNOUT_SENSOR + #undef ADVANCED_PAUSE_FEATURE + #undef FILAMENT_RUNOUT_DISTANCE_MM + #undef FILAMENT_LOAD_UNLOAD_GCODES + #undef DISABLE_INACTIVE_EXTRUDER + #undef FILAMENT_LOAD_UNLOAD_GCODES + #undef EXTRUDER_RUNOUT_PREVENT + #undef PREVENT_COLD_EXTRUSION + #undef PREVENT_LENGTHY_EXTRUDE + #undef THERMAL_PROTECTION_HOTENDS + #undef THERMAL_PROTECTION_PERIOD + #undef WATCH_TEMP_PERIOD + #undef SHOW_TEMP_ADC_VALUES +#endif + #define HAS_CUTTER EITHER(SPINDLE_FEATURE, LASER_FEATURE) #if !defined(__AVR__) || !defined(USBCON) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 3731b1451..4971a7410 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -43,16 +43,6 @@ #define NOT_A_PIN 0 // For PINS_DEBUGGING #endif -#if EXTRUDERS == 0 - #define NO_VOLUMETRICS - #undef FWRETRACT - #undef LIN_ADVANCE - #undef ADVANCED_PAUSE_FEATURE - #undef DISABLE_INACTIVE_EXTRUDER - #undef EXTRUDER_RUNOUT_PREVENT - #undef FILAMENT_LOAD_UNLOAD_GCODES -#endif - #define HAS_CLASSIC_JERK (IS_KINEMATIC || DISABLED(JUNCTION_DEVIATION)) /** @@ -1047,6 +1037,10 @@ #define BED_OR_CHAMBER (HAS_HEATED_BED || HAS_TEMP_CHAMBER) #define HAS_TEMP_SENSOR (HAS_TEMP_HOTEND || BED_OR_CHAMBER) +#if !HAS_TEMP_SENSOR + #undef AUTO_REPORT_TEMPERATURES +#endif + // PID heating #if !HAS_HEATED_BED #undef PIDTEMPBED diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index eaec7529e..f6c8fe2f9 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1476,8 +1476,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." #elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PIN_EXISTS(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." -#elif TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required." +#elif EXTRUDERS && TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required with any extruders." #endif // Pins are required for heaters diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index b7ebc111a..c08067fb6 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -866,7 +866,11 @@ void MarlinUI::draw_status_screen() { char c; uint16_t per; #if HAS_FAN0 - if (blink || thermalManager.fan_speed_scaler[0] < 128) { + if (true + #if EXTRUDERS + && (blink || thermalManager.fan_speed_scaler[0] < 128) + #endif + ) { uint16_t spd = thermalManager.fan_speed[0]; if (blink) c = 'F'; #if ENABLED(ADAPTIVE_FAN_SLOWING) @@ -877,8 +881,10 @@ void MarlinUI::draw_status_screen() { else #endif { - c = 'E'; - per = planner.flow_percentage[0]; + #if EXTRUDERS + c = 'E'; + per = planner.flow_percentage[0]; + #endif } lcd_put_wchar(c); lcd_put_u8str(i16tostr3(per)); diff --git a/Marlin/src/lcd/dogm/dogm_Statusscreen.h b/Marlin/src/lcd/dogm/dogm_Statusscreen.h index aff3a3ae1..46fc9f7f1 100644 --- a/Marlin/src/lcd/dogm/dogm_Statusscreen.h +++ b/Marlin/src/lcd/dogm/dogm_Statusscreen.h @@ -69,10 +69,28 @@ // #if HAS_HEATED_BED && HOTENDS <= 4 - #if HOTENDS == 1 + #if HOTENDS == 0 + + #define STATUS_HEATERS_WIDTH 96 + + const unsigned char status_heaters_bmp[] PROGMEM = { + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000100,B00010000,B01000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,B00001000,B00100000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000010,B00001000,B00100000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000100,B00010000,B01000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,B00100000,B10000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00010000,B01000001,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00010000,B01000001,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,B00100000,B10000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000100,B00010000,B01000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,B11111000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,B11111111,B11111000 + }; + + #elif HOTENDS == 1 #define STATUS_HEATERS_WIDTH 96 - #define STATUS_BED_TEXT_X (STATUS_HEATERS_WIDTH - 10) const unsigned char status_heaters_bmp[] PROGMEM = { B00011111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000100,B00010000,B01000000, @@ -92,7 +110,6 @@ #elif HOTENDS == 2 #define STATUS_HEATERS_WIDTH 96 - #define STATUS_BED_TEXT_X (STATUS_HEATERS_WIDTH - 10) const unsigned char status_heaters_bmp[] PROGMEM = { B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00000000,B00000000,B00000000,B00000100,B00010000,B01000000, @@ -112,7 +129,6 @@ #elif HOTENDS == 3 #define STATUS_HEATERS_WIDTH 96 - #define STATUS_BED_TEXT_X (STATUS_HEATERS_WIDTH - 10) const unsigned char status_heaters_bmp[] PROGMEM = { B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00000100,B00010000,B01000000, @@ -132,7 +148,6 @@ #else // HOTENDS > 3 #define STATUS_HEATERS_WIDTH 120 - #define STATUS_BED_TEXT_X (STATUS_HEATERS_WIDTH - 10) const unsigned char status_heaters_bmp[] PROGMEM = { B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00011111,B11100000,B00000000,B00000100,B00010000,B01000000, @@ -151,9 +166,15 @@ #endif // HOTENDS + #define STATUS_BED_TEXT_X (STATUS_HEATERS_WIDTH - 10) + #else // !HAS_HEATED_BED || HOTENDS > 3 - #if HOTENDS == 1 + #if HOTENDS == 0 + + #define STATUS_HEATERS_WIDTH 0 + + #elif HOTENDS == 1 #define STATUS_HEATERS_WIDTH 12 @@ -229,7 +250,7 @@ B00000011,B00000000,B00000000,B00000011,B00000000,B00000000,B00000011,B00000000,B00000000,B00000011,B00000000 }; - #elif HOTENDS > 4 + #else // HOTENDS > 4 #define STATUS_HEATERS_WIDTH 108 @@ -304,105 +325,101 @@ #endif - #else + #elif HOTENDS >= 2 - #if HOTENDS >= 2 + #ifdef STATUS_HOTEND_ANIM - #ifdef STATUS_HOTEND_ANIM + const unsigned char status_hotend1_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111111,B11110000, + B00111110,B11110000, + B00111100,B11110000, + B00011010,B11100000, + B00011110,B11100000, + B00111110,B11110000, + B00111110,B11110000, + B00111110,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; - const unsigned char status_hotend1_a_bmp[] PROGMEM = { - B00011111,B11100000, - B00111111,B11110000, - B00111110,B11110000, - B00111100,B11110000, - B00011010,B11100000, - B00011110,B11100000, - B00111110,B11110000, - B00111110,B11110000, - B00111110,B11110000, - B00001111,B11000000, - B00000111,B10000000, - B00000011,B00000000 - }; + const unsigned char status_hotend1_b_bmp[] PROGMEM = { + B00011111,B11100000, + B00100000,B00010000, + B00100001,B00010000, + B00100011,B00010000, + B00010101,B00100000, + B00010001,B00100000, + B00100001,B00010000, + B00100001,B00010000, + B00110001,B00110000, + B00001000,B01000000, + B00000100,B10000000, + B00000011,B00000000 + }; - const unsigned char status_hotend1_b_bmp[] PROGMEM = { - B00011111,B11100000, - B00100000,B00010000, - B00100001,B00010000, - B00100011,B00010000, - B00010101,B00100000, - B00010001,B00100000, - B00100001,B00010000, - B00100001,B00010000, - B00110001,B00110000, - B00001000,B01000000, - B00000100,B10000000, - B00000011,B00000000 - }; + const unsigned char status_hotend2_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111111,B11110000, + B00111100,B11110000, + B00111011,B01110000, + B00011111,B01100000, + B00011110,B11100000, + B00111101,B11110000, + B00111011,B11110000, + B00111000,B01110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; - const unsigned char status_hotend2_a_bmp[] PROGMEM = { - B00011111,B11100000, - B00111111,B11110000, - B00111100,B11110000, - B00111011,B01110000, - B00011111,B01100000, - B00011110,B11100000, - B00111101,B11110000, - B00111011,B11110000, - B00111000,B01110000, - B00001111,B11000000, - B00000111,B10000000, - B00000011,B00000000 - }; + const unsigned char status_hotend2_b_bmp[] PROGMEM = { + B00011111,B11100000, + B00100000,B00010000, + B00100011,B00010000, + B00100100,B10010000, + B00010000,B10100000, + B00010001,B00100000, + B00100010,B00010000, + B00100100,B00010000, + B00110111,B10110000, + B00001000,B01000000, + B00000100,B10000000, + B00000011,B00000000 + }; - const unsigned char status_hotend2_b_bmp[] PROGMEM = { - B00011111,B11100000, - B00100000,B00010000, - B00100011,B00010000, - B00100100,B10010000, - B00010000,B10100000, - B00010001,B00100000, - B00100010,B00010000, - B00100100,B00010000, - B00110111,B10110000, - B00001000,B01000000, - B00000100,B10000000, - B00000011,B00000000 - }; + #else - #else + const unsigned char status_hotend1_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111110,B11110000, + B00111100,B11110000, + B00111010,B11110000, + B00011110,B11100000, + B00011110,B11100000, + B00111110,B11110000, + B00111110,B11110000, + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; - const unsigned char status_hotend1_a_bmp[] PROGMEM = { - B00011111,B11100000, - B00111110,B11110000, - B00111100,B11110000, - B00111010,B11110000, - B00011110,B11100000, - B00011110,B11100000, - B00111110,B11110000, - B00111110,B11110000, - B00111111,B11110000, - B00001111,B11000000, - B00000111,B10000000, - B00000011,B00000000 - }; - - const unsigned char status_hotend2_a_bmp[] PROGMEM = { - B00011111,B11100000, - B00111100,B11110000, - B00111011,B01110000, - B00111111,B01110000, - B00011110,B11100000, - B00011101,B11100000, - B00111011,B11110000, - B00111000,B01110000, - B00111111,B11110000, - B00001111,B11000000, - B00000111,B10000000, - B00000011,B00000000 - }; - - #endif + const unsigned char status_hotend2_a_bmp[] PROGMEM = { + B00011111,B11100000, + B00111100,B11110000, + B00111011,B01110000, + B00111111,B01110000, + B00011110,B11100000, + B00011101,B11100000, + B00111011,B11110000, + B00111000,B01110000, + B00111111,B11110000, + B00001111,B11000000, + B00000111,B10000000, + B00000011,B00000000 + }; #endif @@ -573,6 +590,8 @@ #endif + #else + #define STATUS_HEATERS_HEIGHT 20 #endif #endif @@ -1431,6 +1450,10 @@ "Status heaters bitmap (status_heaters_bmp) dimensions don't match data." ); +#else // HOTENDS == 0 + + //#error "Incomplete status header" + #endif // diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index 6fbfba06e..9477bc726 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -93,7 +93,10 @@ #define CHAMBER_ALT() false #endif -#define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE))) +#if HOTENDS + #define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE))) +#endif + #define STATUS_HEATERS_BOT (STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1) #if ENABLED(MARLIN_DEV_MODE) @@ -127,6 +130,11 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const bool blin const bool isHeat = IFBED(BED_ALT(), HOTEND_ALT(heater)); #endif + #ifndef STATUS_HOTEND_TEXT_X + #define STATUS_HOTEND_TEXT_X(N) 0 + #define STATUS_HEATERS_Y 0 + #endif + const uint8_t tx = IFBED(STATUS_BED_TEXT_X, STATUS_HOTEND_TEXT_X(heater)); #if ENABLED(MARLIN_DEV_MODE) @@ -424,8 +432,10 @@ void MarlinUI::draw_status_screen() { // if (PAGE_UNDER(6 + 1 + 12 + 1 + 6 + 1)) { // Extruders - for (uint8_t e = 0; e < MAX_HOTEND_DRAW; ++e) - _draw_heater_status((heater_ind_t)e, blink); + #if HOTENDS + for (uint8_t e = 0; e < MAX_HOTEND_DRAW; ++e) + _draw_heater_status((heater_ind_t)e, blink); + #endif // Heated bed #if DO_DRAW_BED && DISABLED(STATUS_COMBINE_HEATERS) || (HAS_HEATED_BED && ENABLED(STATUS_COMBINE_HEATERS) && HOTENDS <= 4) diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp index 53c9eeb86..ceac9c9d2 100644 --- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp +++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp @@ -497,21 +497,25 @@ void DGUSScreenVariableHandler::HandleTemperatureChanged(DGUS_VP_Variable &var, } void DGUSScreenVariableHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr) { - uint16_t newvalue = swap16(*(uint16_t*)val_ptr); - uint8_t target_extruder; - switch (var.VP) { - default: return; - #if (HOTENDS >= 1) - case VP_Flowrate_E1: target_extruder = 0; break; - #endif - #if (HOTENDS >= 2) - case VP_Flowrate_E2: target_extruder = 1; break; - #endif - } + #if EXTRUDERS + uint16_t newvalue = swap16(*(uint16_t*)val_ptr); + uint8_t target_extruder; + switch (var.VP) { + default: return; + #if (HOTENDS >= 1) + case VP_Flowrate_E1: target_extruder = 0; break; + #endif + #if (HOTENDS >= 2) + case VP_Flowrate_E2: target_extruder = 1; break; + #endif + } - planner.flow_percentage[target_extruder] = newvalue; - planner.refresh_e_factor(target_extruder); - ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel + planner.flow_percentage[target_extruder] = newvalue; + planner.refresh_e_factor(target_extruder); + ScreenHandler.skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel + #else + UNUSED(var); UNUSED(val_ptr); + #endif } void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr) { diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp index 43ffca365..9d29c1f1a 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.cpp +++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp @@ -168,7 +168,7 @@ namespace ExtUI { } void enableHeater(const extruder_t extruder) { - #if HEATER_IDLE_HANDLER + #if HOTENDS && HEATER_IDLE_HANDLER thermalManager.reset_heater_idle_timer(extruder - E0); #endif } @@ -184,14 +184,18 @@ namespace ExtUI { #if HAS_HEATED_CHAMBER case CHAMBER: return; // Chamber has no idle timer #endif - default: thermalManager.reset_heater_idle_timer(heater - H0); + default: + #if HOTENDS + thermalManager.reset_heater_idle_timer(heater - H0); + #endif + break; } #endif } bool isHeaterIdle(const extruder_t extruder) { return false - #if HEATER_IDLE_HANDLER + #if HOTENDS && HEATER_IDLE_HANDLER || thermalManager.hotend_idle[extruder - E0].timed_out #endif ; @@ -206,7 +210,12 @@ namespace ExtUI { #if HAS_HEATED_CHAMBER case CHAMBER: return false; // Chamber has no idle timer #endif - default: return thermalManager.hotend_idle[heater - H0].timed_out; + default: + #if HOTENDS + return thermalManager.hotend_idle[heater - H0].timed_out; + #else + return false; + #endif } #else return false; @@ -841,22 +850,28 @@ namespace ExtUI { } void setTargetTemp_celsius(float value, const heater_t heater) { - constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); - const int16_t e = heater - H0; enableHeater(heater); #if HAS_HEATED_BED if (heater == BED) thermalManager.setTargetBed(clamp(value, 0, BED_MAXTEMP - 10)); else #endif - thermalManager.setTargetHotend(clamp(value, 0, heater_maxtemp[e] - 15), e); + { + #if HOTENDS + static constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); + const int16_t e = heater - H0; + thermalManager.setTargetHotend(clamp(value, 0, heater_maxtemp[e] - 15), e); + #endif + } } void setTargetTemp_celsius(float value, const extruder_t extruder) { - constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); - const int16_t e = extruder - E0; - enableHeater(extruder); - thermalManager.setTargetHotend(clamp(value, 0, heater_maxtemp[e] - 15), e); + #if HOTENDS + constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); + const int16_t e = extruder - E0; + enableHeater(extruder); + thermalManager.setTargetHotend(clamp(value, 0, heater_maxtemp[e] - 15), e); + #endif } void setTargetFan_percent(const float value, const fan_t fan) { diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index 77e1e4a74..98aa2a2b7 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -30,7 +30,9 @@ extern int8_t encoderLine, encoderTopLine, screen_items; extern bool screen_changed; -constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); +#if HOTENDS + constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); +#endif void scroll_screen(const uint8_t limit, const bool is_menu); bool printer_busy(); diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 0d8a562d9..9e2746920 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -43,7 +43,7 @@ #include "../../module/temperature.h" #endif -#ifdef FILAMENT_RUNOUT_DISTANCE_MM +#if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM #include "../../feature/runout.h" float lcd_runout_distance_mm; #endif @@ -178,7 +178,7 @@ void menu_backlash(); #if EXTRUDERS == 1 MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &fc_settings[0].unload_length, 0, extrude_maxlength); - #else // EXTRUDERS > 1 + #elif EXTRUDERS > 1 #define EDIT_FIL_UNLOAD(N) MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E##N, &fc_settings[N-1].unload_length, 0, extrude_maxlength) MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &fc_settings[active_extruder].unload_length, 0, extrude_maxlength); EDIT_FIL_UNLOAD(1); @@ -199,7 +199,7 @@ void menu_backlash(); #if EXTRUDERS == 1 MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &fc_settings[0].load_length, 0, extrude_maxlength); - #else // EXTRUDERS > 1 + #elif EXTRUDERS > 1 #define EDIT_FIL_LOAD(N) MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E##N, &fc_settings[N-1].load_length, 0, extrude_maxlength) MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &fc_settings[active_extruder].load_length, 0, extrude_maxlength); EDIT_FIL_LOAD(1); @@ -219,7 +219,7 @@ void menu_backlash(); #endif // EXTRUDERS > 1 #endif - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM MENU_ITEM_EDIT_CALLBACK(float3, MSG_RUNOUT_DISTANCE_MM, &lcd_runout_distance_mm, 1, 30, []{ runout.set_runout_distance(lcd_runout_distance_mm); }); @@ -620,7 +620,7 @@ void menu_backlash(); #endif // !SLIM_LCD_MENUS void menu_advanced_settings() { - #ifdef FILAMENT_RUNOUT_DISTANCE_MM + #if ENABLED(FILAMENT_RUNOUT_SENSOR) && FILAMENT_RUNOUT_DISTANCE_MM lcd_runout_distance_mm = runout.runout_distance(); #endif START_MENU(); diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index 588500137..b0f713079 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -158,80 +158,85 @@ static void _lcd_move_xyz(PGM_P name, AxisEnum axis) { void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS); } void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS); } void lcd_move_z() { _lcd_move_xyz(PSTR(MSG_MOVE_Z), Z_AXIS); } -static void _lcd_move_e( - #if E_MANUAL > 1 - const int8_t eindex=-1 - #endif -) { - if (ui.use_click()) return ui.goto_previous_screen_no_defer(); - if (ui.encoderPosition) { - if (!ui.processing_manual_move) { - const float diff = float(int16_t(ui.encoderPosition)) * move_menu_scale; - #if IS_KINEMATIC - manual_move_offset += diff; - #else - current_position[E_AXIS] += diff; - #endif - manual_move_to_current(E_AXIS - #if E_MANUAL > 1 - , eindex + +#if E_MANUAL + + static void _lcd_move_e( + #if E_MANUAL > 1 + const int8_t eindex=-1 + #endif + ) { + if (ui.use_click()) return ui.goto_previous_screen_no_defer(); + if (ui.encoderPosition) { + if (!ui.processing_manual_move) { + const float diff = float(int16_t(ui.encoderPosition)) * move_menu_scale; + #if IS_KINEMATIC + manual_move_offset += diff; + #else + current_position[E_AXIS] += diff; #endif - ); - ui.refresh(LCDVIEW_REDRAW_NOW); - } - ui.encoderPosition = 0; - } - if (ui.should_draw()) { - PGM_P pos_label; - #if E_MANUAL == 1 - pos_label = PSTR(MSG_MOVE_E); - #else - switch (eindex) { - default: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E1); break; - case 1: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E2); break; - #if E_MANUAL > 2 - case 2: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E3); break; - #if E_MANUAL > 3 - case 3: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E4); break; - #if E_MANUAL > 4 - case 4: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E5); break; - #if E_MANUAL > 5 - case 5: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E6); break; - #endif // E_MANUAL > 5 - #endif // E_MANUAL > 4 - #endif // E_MANUAL > 3 - #endif // E_MANUAL > 2 + manual_move_to_current(E_AXIS + #if E_MANUAL > 1 + , eindex + #endif + ); + ui.refresh(LCDVIEW_REDRAW_NOW); } - #endif // E_MANUAL > 1 + ui.encoderPosition = 0; + } + if (ui.should_draw()) { + PGM_P pos_label; + #if E_MANUAL == 1 + pos_label = PSTR(MSG_MOVE_E); + #else + switch (eindex) { + default: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E1); break; + case 1: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E2); break; + #if E_MANUAL > 2 + case 2: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E3); break; + #if E_MANUAL > 3 + case 3: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E4); break; + #if E_MANUAL > 4 + case 4: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E5); break; + #if E_MANUAL > 5 + case 5: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E6); break; + #endif // E_MANUAL > 5 + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + } + #endif // E_MANUAL > 1 - draw_edit_screen(pos_label, ftostr41sign(current_position[E_AXIS] - #if IS_KINEMATIC - + manual_move_offset - #endif - #if ENABLED(MANUAL_E_MOVES_RELATIVE) - - manual_move_e_origin - #endif - )); + draw_edit_screen(pos_label, ftostr41sign(current_position[E_AXIS] + #if IS_KINEMATIC + + manual_move_offset + #endif + #if ENABLED(MANUAL_E_MOVES_RELATIVE) + - manual_move_e_origin + #endif + )); + } } -} -inline void lcd_move_e() { _lcd_move_e(); } -#if E_MANUAL > 1 - inline void lcd_move_e0() { _lcd_move_e(0); } - inline void lcd_move_e1() { _lcd_move_e(1); } - #if E_MANUAL > 2 - inline void lcd_move_e2() { _lcd_move_e(2); } - #if E_MANUAL > 3 - inline void lcd_move_e3() { _lcd_move_e(3); } - #if E_MANUAL > 4 - inline void lcd_move_e4() { _lcd_move_e(4); } - #if E_MANUAL > 5 - inline void lcd_move_e5() { _lcd_move_e(5); } - #endif // E_MANUAL > 5 - #endif // E_MANUAL > 4 - #endif // E_MANUAL > 3 - #endif // E_MANUAL > 2 -#endif // E_MANUAL > 1 + inline void lcd_move_e() { _lcd_move_e(); } + #if E_MANUAL > 1 + inline void lcd_move_e0() { _lcd_move_e(0); } + inline void lcd_move_e1() { _lcd_move_e(1); } + #if E_MANUAL > 2 + inline void lcd_move_e2() { _lcd_move_e(2); } + #if E_MANUAL > 3 + inline void lcd_move_e3() { _lcd_move_e(3); } + #if E_MANUAL > 4 + inline void lcd_move_e4() { _lcd_move_e(4); } + #if E_MANUAL > 5 + inline void lcd_move_e5() { _lcd_move_e(5); } + #endif // E_MANUAL > 5 + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 + +#endif // E_MANUAL // // "Motion" > "Move Xmm" > "Move XYZ" submenu @@ -295,23 +300,26 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int void lcd_move_get_x_amount() { _menu_move_distance(X_AXIS, lcd_move_x); } void lcd_move_get_y_amount() { _menu_move_distance(Y_AXIS, lcd_move_y); } void lcd_move_get_z_amount() { _menu_move_distance(Z_AXIS, lcd_move_z); } -void lcd_move_get_e_amount() { _menu_move_distance(E_AXIS, lcd_move_e, -1); } -#if E_MANUAL > 1 - void lcd_move_get_e0_amount() { _menu_move_distance(E_AXIS, lcd_move_e0, 0); } - void lcd_move_get_e1_amount() { _menu_move_distance(E_AXIS, lcd_move_e1, 1); } - #if E_MANUAL > 2 - void lcd_move_get_e2_amount() { _menu_move_distance(E_AXIS, lcd_move_e2, 2); } - #if E_MANUAL > 3 - void lcd_move_get_e3_amount() { _menu_move_distance(E_AXIS, lcd_move_e3, 3); } - #if E_MANUAL > 4 - void lcd_move_get_e4_amount() { _menu_move_distance(E_AXIS, lcd_move_e4, 4); } - #if E_MANUAL > 5 - void lcd_move_get_e5_amount() { _menu_move_distance(E_AXIS, lcd_move_e5, 5); } - #endif // E_MANUAL > 5 - #endif // E_MANUAL > 4 - #endif // E_MANUAL > 3 - #endif // E_MANUAL > 2 -#endif // E_MANUAL > 1 + +#if E_MANUAL + void lcd_move_get_e_amount() { _menu_move_distance(E_AXIS, lcd_move_e, -1); } + #if E_MANUAL > 1 + void lcd_move_get_e0_amount() { _menu_move_distance(E_AXIS, lcd_move_e0, 0); } + void lcd_move_get_e1_amount() { _menu_move_distance(E_AXIS, lcd_move_e1, 1); } + #if E_MANUAL > 2 + void lcd_move_get_e2_amount() { _menu_move_distance(E_AXIS, lcd_move_e2, 2); } + #if E_MANUAL > 3 + void lcd_move_get_e3_amount() { _menu_move_distance(E_AXIS, lcd_move_e3, 3); } + #if E_MANUAL > 4 + void lcd_move_get_e4_amount() { _menu_move_distance(E_AXIS, lcd_move_e4, 4); } + #if E_MANUAL > 5 + void lcd_move_get_e5_amount() { _menu_move_distance(E_AXIS, lcd_move_e5, 5); } + #endif // E_MANUAL > 5 + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 +#endif // E_MANUAL #if ENABLED(DELTA) void lcd_lower_z_to_clip_height() { @@ -396,39 +404,43 @@ void menu_move() { #endif - #if EITHER(SWITCHING_EXTRUDER, SWITCHING_NOZZLE) + #if E_MANUAL + + #if EITHER(SWITCHING_EXTRUDER, SWITCHING_NOZZLE) + + // Only the current... + MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_get_e_amount); + // ...and the non-switching + #if E_MANUAL == 5 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E5, lcd_move_get_e4_amount); + #elif E_MANUAL == 3 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_get_e2_amount); + #endif + + #else + + // Independent extruders with one E-stepper per hotend + MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_get_e_amount); + #if E_MANUAL > 1 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E1, lcd_move_get_e0_amount); + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E2, lcd_move_get_e1_amount); + #if E_MANUAL > 2 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_get_e2_amount); + #if E_MANUAL > 3 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E4, lcd_move_get_e3_amount); + #if E_MANUAL > 4 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E5, lcd_move_get_e4_amount); + #if E_MANUAL > 5 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E6, lcd_move_get_e5_amount); + #endif // E_MANUAL > 5 + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 - // Only the current... - MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_get_e_amount); - // ...and the non-switching - #if E_MANUAL == 5 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E5, lcd_move_get_e4_amount); - #elif E_MANUAL == 3 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_get_e2_amount); #endif - #else - - // Independent extruders with one E-stepper per hotend - MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_get_e_amount); - #if E_MANUAL > 1 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E1, lcd_move_get_e0_amount); - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E2, lcd_move_get_e1_amount); - #if E_MANUAL > 2 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_get_e2_amount); - #if E_MANUAL > 3 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E4, lcd_move_get_e3_amount); - #if E_MANUAL > 4 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E5, lcd_move_get_e4_amount); - #if E_MANUAL > 5 - MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E6, lcd_move_get_e5_amount); - #endif // E_MANUAL > 5 - #endif // E_MANUAL > 4 - #endif // E_MANUAL > 3 - #endif // E_MANUAL > 2 - #endif // E_MANUAL > 1 - - #endif + #endif // E_MANUAL END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp index ad987850f..24b88e829 100644 --- a/Marlin/src/lcd/menu/menu_temperature.cpp +++ b/Marlin/src/lcd/menu/menu_temperature.cpp @@ -48,7 +48,9 @@ uint8_t MarlinUI::preheat_fan_speed[2]; // void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb, const uint8_t fan) { - if (temph > 0) thermalManager.setTargetHotend(_MIN(heater_maxtemp[endnum] - 15, temph), endnum); + #if HOTENDS + if (temph > 0) thermalManager.setTargetHotend(_MIN(heater_maxtemp[endnum] - 15, temph), endnum); + #endif #if HAS_HEATED_BED if (tempb >= 0) thermalManager.setTargetBed(tempb); #else @@ -165,12 +167,16 @@ void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb #if HAS_TEMP_HOTEND || HAS_HEATED_BED - void lcd_preheat_m1_e0_only() { _lcd_preheat(0, ui.preheat_hotend_temp[0], -1, ui.preheat_fan_speed[0]); } - void lcd_preheat_m2_e0_only() { _lcd_preheat(0, ui.preheat_hotend_temp[1], -1, ui.preheat_fan_speed[1]); } + #if HOTENDS + void lcd_preheat_m1_e0_only() { _lcd_preheat(0, ui.preheat_hotend_temp[0], -1, ui.preheat_fan_speed[0]); } + void lcd_preheat_m2_e0_only() { _lcd_preheat(0, ui.preheat_hotend_temp[1], -1, ui.preheat_fan_speed[1]); } + #endif #if HAS_HEATED_BED - void lcd_preheat_m1_e0() { _lcd_preheat(0, ui.preheat_hotend_temp[0], ui.preheat_bed_temp[0], ui.preheat_fan_speed[0]); } - void lcd_preheat_m2_e0() { _lcd_preheat(0, ui.preheat_hotend_temp[1], ui.preheat_bed_temp[1], ui.preheat_fan_speed[1]); } + #if HOTENDS + void lcd_preheat_m1_e0() { _lcd_preheat(0, ui.preheat_hotend_temp[0], ui.preheat_bed_temp[0], ui.preheat_fan_speed[0]); } + void lcd_preheat_m2_e0() { _lcd_preheat(0, ui.preheat_hotend_temp[1], ui.preheat_bed_temp[1], ui.preheat_fan_speed[1]); } + #endif void lcd_preheat_m1_bedonly() { _lcd_preheat(0, 0, ui.preheat_bed_temp[0], ui.preheat_fan_speed[0]); } void lcd_preheat_m2_bedonly() { _lcd_preheat(0, 0, ui.preheat_bed_temp[1], ui.preheat_fan_speed[1]); } #endif @@ -313,7 +319,7 @@ void menu_temperature() { // #if HOTENDS == 1 MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - 15, thermalManager.start_watching_E0); - #else // HOTENDS > 1 + #elif HOTENDS > 1 #define EDIT_TARGET(N) MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_LCD_N##N, &thermalManager.temp_hotend[N].target, 0, HEATER_##N##_MAXTEMP - 15, thermalManager.start_watching_E##N) EDIT_TARGET(0); EDIT_TARGET(1); diff --git a/Marlin/src/lcd/menu/menu_tune.cpp b/Marlin/src/lcd/menu/menu_tune.cpp index 1c038ea13..3198e6a1b 100644 --- a/Marlin/src/lcd/menu/menu_tune.cpp +++ b/Marlin/src/lcd/menu/menu_tune.cpp @@ -144,7 +144,7 @@ void menu_tune() { // #if HOTENDS == 1 MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - 15, thermalManager.start_watching_E0); - #else // HOTENDS > 1 + #elif HOTENDS > 1 #define EDIT_NOZZLE(N) MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_LCD_N##N, &thermalManager.temp_hotend[N].target, 0, HEATER_##N##_MAXTEMP - 15, thermalManager.start_watching_E##N) EDIT_NOZZLE(0); EDIT_NOZZLE(1); diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index d122c6e12..5d0a0300b 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -309,7 +309,9 @@ typedef struct SettingsDataStruct { // // ADVANCED_PAUSE_FEATURE // - fil_change_settings_t fc_settings[EXTRUDERS]; // M603 T U L + #if EXTRUDERS + fil_change_settings_t fc_settings[EXTRUDERS]; // M603 T U L + #endif // // Tool-change settings @@ -367,7 +369,7 @@ void MarlinSettings::postprocess() { #if DISABLED(NO_VOLUMETRICS) planner.calculate_volumetric_multipliers(); - #else + #elif EXTRUDERS for (uint8_t i = COUNT(planner.e_factor); i--;) planner.refresh_e_factor(i); #endif @@ -759,7 +761,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(ui_preheat_hotend_temp); - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU const int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp, (&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp; const uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed; @@ -1164,6 +1166,7 @@ void MarlinSettings::postprocess() { // // Advanced Pause filament load & unload lengths // + #if EXTRUDERS { #if DISABLED(ADVANCED_PAUSE_FEATURE) const fil_change_settings_t fc_settings[EXTRUDERS] = { 0, 0 }; @@ -1171,6 +1174,7 @@ void MarlinSettings::postprocess() { _FIELD_TEST(fc_settings); EEPROM_WRITE(fc_settings); } + #endif // // Multiple Extruders @@ -1560,7 +1564,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(ui_preheat_hotend_temp); - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp, (&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp; uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed; @@ -1968,6 +1972,7 @@ void MarlinSettings::postprocess() { // // Advanced Pause filament load & unload lengths // + #if EXTRUDERS { #if DISABLED(ADVANCED_PAUSE_FEATURE) fil_change_settings_t fc_settings[EXTRUDERS]; @@ -1975,6 +1980,7 @@ void MarlinSettings::postprocess() { _FIELD_TEST(fc_settings); EEPROM_READ(fc_settings); } + #endif // // Tool-change settings @@ -2410,7 +2416,7 @@ void MarlinSettings::reset() { // Preheat parameters // - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU ui.preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND; ui.preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND; ui.preheat_bed_temp[0] = PREHEAT_1_TEMP_BED; @@ -2956,7 +2962,7 @@ void MarlinSettings::reset() { #endif // [XYZ]_DUAL_ENDSTOPS - #if HAS_LCD_MENU + #if HOTENDS && HAS_LCD_MENU CONFIG_ECHO_HEADING("Material heatup parameters:"); for (uint8_t i = 0; i < COUNT(ui.preheat_hotend_temp); i++) { diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 7c637f9cb..5a8a42d7f 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -124,8 +124,10 @@ XYZ_DEFS(signed char, home_dir, HOME_DIR); #if HAS_HOTEND_OFFSET extern float hotend_offset[XYZ][HOTENDS]; void reset_hotend_offsets(); -#else +#elif HOTENDS > 0 constexpr float hotend_offset[XYZ][HOTENDS] = { { 0 }, { 0 }, { 0 } }; +#else + constexpr float hotend_offset[XYZ][1] = { { 0 }, { 0 }, { 0 } }; #endif typedef struct { float min, max; } axis_limits_t; diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 58934a467..55e846286 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -147,9 +147,10 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step 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] = ARRAY_BY_EXTRUDERS1(1.0f); // The flow percentage and volumetric multiplier combine to scale E movement +#if EXTRUDERS + int16_t Planner::flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); // Extrusion factor for each extruder + float Planner::e_factor[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0f); // The flow percentage and volumetric multiplier combine to scale E movement +#endif #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 @@ -1632,7 +1633,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move, db = target[B_AXIS] - position[B_AXIS], dc = target[C_AXIS] - position[C_AXIS]; - int32_t de = target[E_AXIS] - position[E_AXIS]; + #if EXTRUDERS + int32_t de = target[E_AXIS] - position[E_AXIS]; + #else + constexpr int32_t de = 0; + #endif /* <-- add a slash to enable SERIAL_ECHOPAIR(" _populate_block FR:", fr_mm_s); @@ -1642,8 +1647,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move, SERIAL_ECHOPAIR(" (", db); SERIAL_ECHOPAIR(" steps) C:", target[C_AXIS]); SERIAL_ECHOPAIR(" (", dc); - SERIAL_ECHOPAIR(" steps) E:", target[E_AXIS]); - SERIAL_ECHOPAIR(" (", de); + #if EXTRUDERS + SERIAL_ECHOPAIR(" steps) E:", target[E_AXIS]); + SERIAL_ECHOPAIR(" (", de); + #endif SERIAL_ECHOLNPGM(" steps)"); //*/ @@ -1712,8 +1719,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif if (de < 0) SBI(dm, E_AXIS); - const float esteps_float = de * e_factor[extruder]; - const uint32_t esteps = ABS(esteps_float) + 0.5f; + #if EXTRUDERS + const float esteps_float = de * e_factor[extruder]; + const uint32_t esteps = ABS(esteps_float) + 0.5f; + #else + constexpr uint32_t esteps = 0; + #endif // Clear all flags, including the "busy" bit block->flag = 0x00; @@ -1781,10 +1792,17 @@ bool Planner::_populate_block(block_t * const block, bool split_move, delta_mm[B_AXIS] = db * steps_to_mm[B_AXIS]; delta_mm[C_AXIS] = dc * steps_to_mm[C_AXIS]; #endif - delta_mm[E_AXIS] = esteps_float * steps_to_mm[E_AXIS_N(extruder)]; + + #if EXTRUDERS + delta_mm[E_AXIS] = esteps_float * steps_to_mm[E_AXIS_N(extruder)]; + #endif if (block->steps[A_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[B_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[C_AXIS] < MIN_STEPS_PER_SEGMENT) { - block->millimeters = ABS(delta_mm[E_AXIS]); + block->millimeters = (0 + #if EXTRUDERS + + ABS(delta_mm[E_AXIS]) + #endif + ); } else { if (millimeters) @@ -1816,7 +1834,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif } - block->steps[E_AXIS] = esteps; + #if EXTRUDERS + block->steps[E_AXIS] = esteps; + #endif + block->step_event_count = _MAX(block->steps[A_AXIS], block->steps[B_AXIS], block->steps[C_AXIS], esteps); // Bail if this is a zero-length block @@ -1874,129 +1895,131 @@ bool Planner::_populate_block(block_t * const block, bool split_move, #endif // Enable extruder(s) - if (esteps) { - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif + #if EXTRUDERS + if (esteps) { + #if ENABLED(AUTO_POWER_CONTROL) + powerManager.power_on(); + #endif - #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder - #define DISABLE_IDLE_E(N) if (!g_uc_extruder_last_move[N]) disable_E##N(); + #define DISABLE_IDLE_E(N) if (!g_uc_extruder_last_move[N]) disable_E##N(); - for (uint8_t i = 0; i < EXTRUDERS; i++) - if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--; + for (uint8_t i = 0; i < EXTRUDERS; i++) + if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--; - switch (extruder) { - case 0: + switch (extruder) { + case 0: + #if EXTRUDERS > 1 + DISABLE_IDLE_E(1); + #if EXTRUDERS > 2 + DISABLE_IDLE_E(2); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #if EXTRUDERS > 5 + DISABLE_IDLE_E(5); + #endif // EXTRUDERS > 5 + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + enable_E0(); + g_uc_extruder_last_move[0] = (BLOCK_BUFFER_SIZE) * 2; + #if HAS_DUPLICATION_MODE + if (extruder_duplication_enabled) { + enable_E1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + } + #endif + break; #if EXTRUDERS > 1 - DISABLE_IDLE_E(1); + case 1: + DISABLE_IDLE_E(0); + #if EXTRUDERS > 2 + DISABLE_IDLE_E(2); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #if EXTRUDERS > 5 + DISABLE_IDLE_E(5); + #endif // EXTRUDERS > 5 + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + enable_E1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + break; #if EXTRUDERS > 2 - DISABLE_IDLE_E(2); + case 2: + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #if EXTRUDERS > 5 + DISABLE_IDLE_E(5); + #endif + #endif + #endif + enable_E2(); + g_uc_extruder_last_move[2] = (BLOCK_BUFFER_SIZE) * 2; + break; #if EXTRUDERS > 3 - DISABLE_IDLE_E(3); + case 3: + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + DISABLE_IDLE_E(2); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #if EXTRUDERS > 5 + DISABLE_IDLE_E(5); + #endif + #endif + enable_E3(); + g_uc_extruder_last_move[3] = (BLOCK_BUFFER_SIZE) * 2; + break; #if EXTRUDERS > 4 - DISABLE_IDLE_E(4); + case 4: + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + DISABLE_IDLE_E(2); + DISABLE_IDLE_E(3); + #if EXTRUDERS > 5 + DISABLE_IDLE_E(5); + #endif + enable_E4(); + g_uc_extruder_last_move[4] = (BLOCK_BUFFER_SIZE) * 2; + break; #if EXTRUDERS > 5 - DISABLE_IDLE_E(5); + case 5: + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + DISABLE_IDLE_E(2); + DISABLE_IDLE_E(3); + DISABLE_IDLE_E(4); + enable_E5(); + g_uc_extruder_last_move[5] = (BLOCK_BUFFER_SIZE) * 2; + break; #endif // EXTRUDERS > 5 #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 #endif // EXTRUDERS > 1 - enable_E0(); - g_uc_extruder_last_move[0] = (BLOCK_BUFFER_SIZE) * 2; - #if HAS_DUPLICATION_MODE - if (extruder_duplication_enabled) { - enable_E1(); - g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; - } - #endif - break; - #if EXTRUDERS > 1 - case 1: - DISABLE_IDLE_E(0); - #if EXTRUDERS > 2 - DISABLE_IDLE_E(2); - #if EXTRUDERS > 3 - DISABLE_IDLE_E(3); - #if EXTRUDERS > 4 - DISABLE_IDLE_E(4); - #if EXTRUDERS > 5 - DISABLE_IDLE_E(5); - #endif // EXTRUDERS > 5 - #endif // EXTRUDERS > 4 - #endif // EXTRUDERS > 3 - #endif // EXTRUDERS > 2 - enable_E1(); - g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; - break; - #if EXTRUDERS > 2 - case 2: - DISABLE_IDLE_E(0); - DISABLE_IDLE_E(1); - #if EXTRUDERS > 3 - DISABLE_IDLE_E(3); - #if EXTRUDERS > 4 - DISABLE_IDLE_E(4); - #if EXTRUDERS > 5 - DISABLE_IDLE_E(5); - #endif - #endif - #endif - enable_E2(); - g_uc_extruder_last_move[2] = (BLOCK_BUFFER_SIZE) * 2; - break; - #if EXTRUDERS > 3 - case 3: - DISABLE_IDLE_E(0); - DISABLE_IDLE_E(1); - DISABLE_IDLE_E(2); - #if EXTRUDERS > 4 - DISABLE_IDLE_E(4); - #if EXTRUDERS > 5 - DISABLE_IDLE_E(5); - #endif - #endif - enable_E3(); - g_uc_extruder_last_move[3] = (BLOCK_BUFFER_SIZE) * 2; - break; - #if EXTRUDERS > 4 - case 4: - DISABLE_IDLE_E(0); - DISABLE_IDLE_E(1); - DISABLE_IDLE_E(2); - DISABLE_IDLE_E(3); - #if EXTRUDERS > 5 - DISABLE_IDLE_E(5); - #endif - enable_E4(); - g_uc_extruder_last_move[4] = (BLOCK_BUFFER_SIZE) * 2; - break; - #if EXTRUDERS > 5 - case 5: - DISABLE_IDLE_E(0); - DISABLE_IDLE_E(1); - DISABLE_IDLE_E(2); - DISABLE_IDLE_E(3); - DISABLE_IDLE_E(4); - enable_E5(); - g_uc_extruder_last_move[5] = (BLOCK_BUFFER_SIZE) * 2; - break; - #endif // EXTRUDERS > 5 - #endif // EXTRUDERS > 4 - #endif // EXTRUDERS > 3 - #endif // EXTRUDERS > 2 - #endif // EXTRUDERS > 1 - } - #else - enable_E0(); - enable_E1(); - enable_E2(); - enable_E3(); - enable_E4(); - enable_E5(); - #endif - } + } + #else + enable_E0(); + enable_E1(); + enable_E2(); + enable_E3(); + enable_E4(); + enable_E5(); + #endif + } + #endif // EXTRUDERS if (esteps) NOLESS(fr_mm_s, settings.min_feedrate_mm_s); diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 77cde6e2b..2f9d52698 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -226,9 +226,10 @@ class Planner { static uint8_t last_extruder; // Respond to extruder change #endif - 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 EXTRUDERS + 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 + #endif #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 @@ -357,13 +358,15 @@ 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.01f - #if DISABLED(NO_VOLUMETRICS) - * volumetric_multiplier[e] - #endif - ); - } + #if EXTRUDERS + FORCE_INLINE static void refresh_e_factor(const uint8_t e) { + e_factor[e] = (flow_percentage[e] * 0.01f + #if DISABLED(NO_VOLUMETRICS) + * volumetric_multiplier[e] + #endif + ); + } + #endif // Manage fans, paste pressure, etc. static void check_axes_activity(); diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 4cac00371..2f6465287 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -112,11 +112,9 @@ Temperature thermalManager; bool Temperature::adaptive_fan_slowing = true; #endif -hotend_info_t Temperature::temp_hotend[HOTENDS - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - + 1 - #endif -]; // = { 0 } +#if HOTENDS + hotend_info_t Temperature::temp_hotend[HOTEND_TEMPS]; // = { 0 } +#endif #if ENABLED(AUTO_POWER_E_FANS) uint8_t Temperature::autofan_speed[HOTENDS]; // = { 0 } @@ -283,15 +281,17 @@ volatile bool Temperature::temp_meas_ready = false; #define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) < (HEATER_##N##_RAW_HI_TEMP) ? 1 : -1) -// Init mintemp and maxtemp with extreme values to prevent false errors during startup -constexpr temp_range_t sensor_heater_0 { HEATER_0_RAW_LO_TEMP, HEATER_0_RAW_HI_TEMP, 0, 16383 }, - sensor_heater_1 { HEATER_1_RAW_LO_TEMP, HEATER_1_RAW_HI_TEMP, 0, 16383 }, - sensor_heater_2 { HEATER_2_RAW_LO_TEMP, HEATER_2_RAW_HI_TEMP, 0, 16383 }, - sensor_heater_3 { HEATER_3_RAW_LO_TEMP, HEATER_3_RAW_HI_TEMP, 0, 16383 }, - sensor_heater_4 { HEATER_4_RAW_LO_TEMP, HEATER_4_RAW_HI_TEMP, 0, 16383 }, - sensor_heater_5 { HEATER_5_RAW_LO_TEMP, HEATER_5_RAW_HI_TEMP, 0, 16383 }; +#if HOTENDS + // Init mintemp and maxtemp with extreme values to prevent false errors during startup + constexpr temp_range_t sensor_heater_0 { HEATER_0_RAW_LO_TEMP, HEATER_0_RAW_HI_TEMP, 0, 16383 }, + sensor_heater_1 { HEATER_1_RAW_LO_TEMP, HEATER_1_RAW_HI_TEMP, 0, 16383 }, + sensor_heater_2 { HEATER_2_RAW_LO_TEMP, HEATER_2_RAW_HI_TEMP, 0, 16383 }, + sensor_heater_3 { HEATER_3_RAW_LO_TEMP, HEATER_3_RAW_HI_TEMP, 0, 16383 }, + sensor_heater_4 { HEATER_4_RAW_LO_TEMP, HEATER_4_RAW_HI_TEMP, 0, 16383 }, + sensor_heater_5 { HEATER_5_RAW_LO_TEMP, HEATER_5_RAW_HI_TEMP, 0, 16383 }; -temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0, sensor_heater_1, sensor_heater_2, sensor_heater_3, sensor_heater_4, sensor_heater_5); + temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0, sensor_heater_1, sensor_heater_2, sensor_heater_3, sensor_heater_4, sensor_heater_5); +#endif #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED uint8_t Temperature::consecutive_low_temperature_error[HOTENDS] = { 0 }; @@ -627,17 +627,20 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0 * Class and Instance Methods */ -Temperature::Temperature() { } - int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { switch (heater_id) { - default: return temp_hotend[heater_id].soft_pwm_amount; #if HAS_HEATED_BED case H_BED: return temp_bed.soft_pwm_amount; #endif #if HAS_HEATED_CHAMBER case H_CHAMBER: return temp_chamber.soft_pwm_amount; #endif + default: + #if HOTENDS + return temp_hotend[heater_id].soft_pwm_amount; + #else + return 0; + #endif } } @@ -816,114 +819,118 @@ void Temperature::min_temp_error(const heater_ind_t heater) { _temp_error(heater, PSTR(MSG_T_MINTEMP), TEMP_ERR_PSTR(MSG_ERR_MINTEMP, heater)); } -float Temperature::get_pid_output_hotend(const uint8_t e) { - #if HOTENDS == 1 - #define _HOTEND_TEST true - #else - #define _HOTEND_TEST (e == active_extruder) - #endif - E_UNUSED(); - const uint8_t ee = HOTEND_INDEX; - float pid_output; - #if ENABLED(PIDTEMP) - #if DISABLED(PID_OPENLOOP) - static hotend_pid_t work_pid[HOTENDS]; - static float temp_iState[HOTENDS] = { 0 }, - temp_dState[HOTENDS] = { 0 }; - static bool pid_reset[HOTENDS] = { false }; - const float pid_error = temp_hotend[ee].target - temp_hotend[ee].celsius; +#if HOTENDS - if (temp_hotend[ee].target == 0 - || pid_error < -(PID_FUNCTIONAL_RANGE) - #if HEATER_IDLE_HANDLER - || hotend_idle[ee].timed_out - #endif - ) { - pid_output = 0; - pid_reset[ee] = true; - } - else if (pid_error > PID_FUNCTIONAL_RANGE) { - pid_output = BANG_MAX; - pid_reset[ee] = true; - } - else { - if (pid_reset[ee]) { - temp_iState[ee] = 0.0; - work_pid[ee].Kd = 0.0; - pid_reset[ee] = false; - } - - work_pid[ee].Kd = work_pid[ee].Kd + PID_K2 * (PID_PARAM(Kd, ee) * (temp_dState[ee] - temp_hotend[ee].celsius) - work_pid[ee].Kd); - const float max_power_over_i_gain = float(PID_MAX) / PID_PARAM(Ki, ee) - float(MIN_POWER); - temp_iState[ee] = constrain(temp_iState[ee] + pid_error, 0, max_power_over_i_gain); - work_pid[ee].Kp = PID_PARAM(Kp, ee) * pid_error; - work_pid[ee].Ki = PID_PARAM(Ki, ee) * temp_iState[ee]; - - pid_output = work_pid[ee].Kp + work_pid[ee].Ki + work_pid[ee].Kd + float(MIN_POWER); - - #if ENABLED(PID_EXTRUSION_SCALING) - work_pid[ee].Kc = 0; - if (_HOTEND_TEST) { - const long e_position = stepper.position(E_AXIS); - if (e_position > last_e_position) { - lpq[lpq_ptr] = e_position - last_e_position; - last_e_position = e_position; - } - else - lpq[lpq_ptr] = 0; - - if (++lpq_ptr >= lpq_len) lpq_ptr = 0; - work_pid[ee].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, ee); - pid_output += work_pid[ee].Kc; - } - #endif // PID_EXTRUSION_SCALING - - LIMIT(pid_output, 0, PID_MAX); - } - temp_dState[ee] = temp_hotend[ee].celsius; - - #else // PID_OPENLOOP - - const float pid_output = constrain(temp_hotend[ee].target, 0, PID_MAX); - - #endif // PID_OPENLOOP - - #if ENABLED(PID_DEBUG) - if (e == active_extruder) { - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR( - MSG_PID_DEBUG, ee, - MSG_PID_DEBUG_INPUT, temp_hotend[ee].celsius, - MSG_PID_DEBUG_OUTPUT, pid_output - ); - #if DISABLED(PID_OPENLOOP) - SERIAL_ECHOPAIR( - MSG_PID_DEBUG_PTERM, work_pid[ee].Kp, - MSG_PID_DEBUG_ITERM, work_pid[ee].Ki, - MSG_PID_DEBUG_DTERM, work_pid[ee].Kd - #if ENABLED(PID_EXTRUSION_SCALING) - , MSG_PID_DEBUG_CTERM, work_pid[ee].Kc - #endif - ); - #endif - SERIAL_EOL(); - } - #endif // PID_DEBUG - - #else // No PID enabled - - #if HEATER_IDLE_HANDLER - #define _TIMED_OUT_TEST hotend_idle[ee].timed_out + float Temperature::get_pid_output_hotend(const uint8_t e) { + #if HOTENDS == 1 + #define _HOTEND_TEST true #else - #define _TIMED_OUT_TEST false + #define _HOTEND_TEST (e == active_extruder) #endif - pid_output = (!_TIMED_OUT_TEST && temp_hotend[ee].celsius < temp_hotend[ee].target) ? BANG_MAX : 0; - #undef _TIMED_OUT_TEST + E_UNUSED(); + const uint8_t ee = HOTEND_INDEX; + float pid_output; + #if ENABLED(PIDTEMP) + #if DISABLED(PID_OPENLOOP) + static hotend_pid_t work_pid[HOTENDS]; + static float temp_iState[HOTENDS] = { 0 }, + temp_dState[HOTENDS] = { 0 }; + static bool pid_reset[HOTENDS] = { false }; + const float pid_error = temp_hotend[ee].target - temp_hotend[ee].celsius; - #endif + if (temp_hotend[ee].target == 0 + || pid_error < -(PID_FUNCTIONAL_RANGE) + #if HEATER_IDLE_HANDLER + || hotend_idle[ee].timed_out + #endif + ) { + pid_output = 0; + pid_reset[ee] = true; + } + else if (pid_error > PID_FUNCTIONAL_RANGE) { + pid_output = BANG_MAX; + pid_reset[ee] = true; + } + else { + if (pid_reset[ee]) { + temp_iState[ee] = 0.0; + work_pid[ee].Kd = 0.0; + pid_reset[ee] = false; + } - return pid_output; -} + work_pid[ee].Kd = work_pid[ee].Kd + PID_K2 * (PID_PARAM(Kd, ee) * (temp_dState[ee] - temp_hotend[ee].celsius) - work_pid[ee].Kd); + const float max_power_over_i_gain = float(PID_MAX) / PID_PARAM(Ki, ee) - float(MIN_POWER); + temp_iState[ee] = constrain(temp_iState[ee] + pid_error, 0, max_power_over_i_gain); + work_pid[ee].Kp = PID_PARAM(Kp, ee) * pid_error; + work_pid[ee].Ki = PID_PARAM(Ki, ee) * temp_iState[ee]; + + pid_output = work_pid[ee].Kp + work_pid[ee].Ki + work_pid[ee].Kd + float(MIN_POWER); + + #if ENABLED(PID_EXTRUSION_SCALING) + work_pid[ee].Kc = 0; + if (_HOTEND_TEST) { + const long e_position = stepper.position(E_AXIS); + if (e_position > last_e_position) { + lpq[lpq_ptr] = e_position - last_e_position; + last_e_position = e_position; + } + else + lpq[lpq_ptr] = 0; + + if (++lpq_ptr >= lpq_len) lpq_ptr = 0; + work_pid[ee].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, ee); + pid_output += work_pid[ee].Kc; + } + #endif // PID_EXTRUSION_SCALING + + LIMIT(pid_output, 0, PID_MAX); + } + temp_dState[ee] = temp_hotend[ee].celsius; + + #else // PID_OPENLOOP + + const float pid_output = constrain(temp_hotend[ee].target, 0, PID_MAX); + + #endif // PID_OPENLOOP + + #if ENABLED(PID_DEBUG) + if (e == active_extruder) { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR( + MSG_PID_DEBUG, ee, + MSG_PID_DEBUG_INPUT, temp_hotend[ee].celsius, + MSG_PID_DEBUG_OUTPUT, pid_output + ); + #if DISABLED(PID_OPENLOOP) + SERIAL_ECHOPAIR( + MSG_PID_DEBUG_PTERM, work_pid[ee].Kp, + MSG_PID_DEBUG_ITERM, work_pid[ee].Ki, + MSG_PID_DEBUG_DTERM, work_pid[ee].Kd + #if ENABLED(PID_EXTRUSION_SCALING) + , MSG_PID_DEBUG_CTERM, work_pid[ee].Kc + #endif + ); + #endif + SERIAL_EOL(); + } + #endif // PID_DEBUG + + #else // No PID enabled + + #if HEATER_IDLE_HANDLER + #define _TIMED_OUT_TEST hotend_idle[ee].timed_out + #else + #define _TIMED_OUT_TEST false + #endif + pid_output = (!_TIMED_OUT_TEST && temp_hotend[ee].celsius < temp_hotend[ee].target) ? BANG_MAX : 0; + #undef _TIMED_OUT_TEST + + #endif + + return pid_output; + } + +#endif // HOTENDS #if ENABLED(PIDTEMPBED) @@ -1025,44 +1032,46 @@ void Temperature::manage_heater() { if (temp_hotend[1].celsius < _MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(H_E1); #endif - #if HAS_THERMAL_PROTECTION || DISABLED(PIDTEMPBED) || HAS_AUTO_FAN || HEATER_IDLE_HANDLER - millis_t ms = millis(); - #endif + millis_t ms = millis(); - HOTEND_LOOP() { - #if ENABLED(THERMAL_PROTECTION_HOTENDS) - if (degHotend(e) > temp_range[e].maxtemp) - _temp_error((heater_ind_t)e, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, e)); - #endif + #if HOTENDS - #if HEATER_IDLE_HANDLER - hotend_idle[e].update(ms); - #endif + HOTEND_LOOP() { + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + if (degHotend(e) > temp_range[e].maxtemp) + _temp_error((heater_ind_t)e, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, e)); + #endif - #if ENABLED(THERMAL_PROTECTION_HOTENDS) - // Check for thermal runaway - thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); - #endif + #if HEATER_IDLE_HANDLER + hotend_idle[e].update(ms); + #endif - temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + // Check for thermal runaway + thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); + #endif - #if WATCH_HOTENDS - // Make sure temperature is increasing - if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder? - if (degHotend(e) < watch_hotend[e].target) // Failed to increase enough? - _temp_error((heater_ind_t)e, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, e)); - else // Start again if the target is still far off - start_watching_hotend(e); - } - #endif + temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - // Make sure measured temperatures are close together - if (ABS(temp_hotend[0].celsius - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) - _temp_error(H_E0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP)); - #endif + #if WATCH_HOTENDS + // Make sure temperature is increasing + if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder? + if (degHotend(e) < watch_hotend[e].target) // Failed to increase enough? + _temp_error((heater_ind_t)e, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, e)); + else // Start again if the target is still far off + start_watching_hotend(e); + } + #endif - } // HOTEND_LOOP + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + // Make sure measured temperatures are close together + if (ABS(temp_hotend[0].celsius - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) + _temp_error(H_E0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP)); + #endif + + } // HOTEND_LOOP + + #endif // HOTENDS #if HAS_AUTO_FAN if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently @@ -1206,6 +1215,8 @@ void Temperature::manage_heater() { //temp_bed.soft_pwm_amount = WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP) ? (int)get_pid_output_chamber() >> 1 : 0; #endif // HAS_HEATED_CHAMBER + + UNUSED(ms); } #define TEMP_AD595(RAW) ((RAW) * 5.0 * 100.0 / 1024.0 / (OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET) @@ -1358,98 +1369,100 @@ void Temperature::manage_heater() { } #endif -// Derived from RepRap FiveD extruder::getTemperature() -// For hot end temperature measurement. -float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) { - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - if (e > HOTENDS) - #else - if (e >= HOTENDS) - #endif - { - SERIAL_ERROR_START(); - SERIAL_ECHO((int)e); - SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER_NUM); - kill(); - return 0.0; +#if HOTENDS + // Derived from RepRap FiveD extruder::getTemperature() + // For hot end temperature measurement. + float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) { + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + if (e > HOTENDS) + #else + if (e >= HOTENDS) + #endif + { + SERIAL_ERROR_START(); + SERIAL_ECHO((int)e); + SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER_NUM); + kill(); + return 0.0; + } + + switch (e) { + case 0: + #if ENABLED(HEATER_0_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_0, raw); + #elif ENABLED(HEATER_0_USES_MAX6675) + return raw * 0.25; + #elif ENABLED(HEATER_0_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_0_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + case 1: + #if ENABLED(HEATER_1_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_1, raw); + #elif ENABLED(HEATER_1_USES_MAX6675) + return raw * 0.25; + #elif ENABLED(HEATER_1_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_1_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + case 2: + #if ENABLED(HEATER_2_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_2, raw); + #elif ENABLED(HEATER_2_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_2_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + case 3: + #if ENABLED(HEATER_3_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_3, raw); + #elif ENABLED(HEATER_3_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_3_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + case 4: + #if ENABLED(HEATER_4_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_4, raw); + #elif ENABLED(HEATER_4_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_4_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + case 5: + #if ENABLED(HEATER_5_USER_THERMISTOR) + return user_thermistor_to_deg_c(CTI_HOTEND_5, raw); + #elif ENABLED(HEATER_5_USES_AD595) + return TEMP_AD595(raw); + #elif ENABLED(HEATER_5_USES_AD8495) + return TEMP_AD8495(raw); + #else + break; + #endif + default: break; } - switch (e) { - case 0: - #if ENABLED(HEATER_0_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_0, raw); - #elif ENABLED(HEATER_0_USES_MAX6675) - return raw * 0.25; - #elif ENABLED(HEATER_0_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_0_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - case 1: - #if ENABLED(HEATER_1_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_1, raw); - #elif ENABLED(HEATER_1_USES_MAX6675) - return raw * 0.25; - #elif ENABLED(HEATER_1_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_1_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - case 2: - #if ENABLED(HEATER_2_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_2, raw); - #elif ENABLED(HEATER_2_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_2_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - case 3: - #if ENABLED(HEATER_3_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_3, raw); - #elif ENABLED(HEATER_3_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_3_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - case 4: - #if ENABLED(HEATER_4_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_4, raw); - #elif ENABLED(HEATER_4_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_4_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - case 5: - #if ENABLED(HEATER_5_USER_THERMISTOR) - return user_thermistor_to_deg_c(CTI_HOTEND_5, raw); - #elif ENABLED(HEATER_5_USES_AD595) - return TEMP_AD595(raw); - #elif ENABLED(HEATER_5_USES_AD8495) - return TEMP_AD8495(raw); - #else - break; - #endif - default: break; + #if HOTEND_USES_THERMISTOR + // Thermistor with conversion table? + const short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]); + SCAN_THERMISTOR_TABLE((*tt), heater_ttbllen_map[e]); + #endif + + return 0; } - - #if HOTEND_USES_THERMISTOR - // Thermistor with conversion table? - const short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]); - SCAN_THERMISTOR_TABLE((*tt), heater_ttbllen_map[e]); - #endif - - return 0; -} +#endif // HOTENDS #if HAS_HEATED_BED // Derived from RepRap FiveD extruder::getTemperature() @@ -1500,7 +1513,9 @@ void Temperature::updateTemperaturesFromRawValues() { #if ENABLED(HEATER_1_USES_MAX6675) temp_hotend[1].raw = READ_MAX6675(1); #endif - HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].raw, e); + #if HOTENDS + HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].raw, e); + #endif #if HAS_HEATED_BED temp_bed.celsius = analog_to_celsius_bed(temp_bed.raw); #endif @@ -1802,7 +1817,7 @@ void Temperature::init() { #endif // HOTENDS > 2 #endif // HOTENDS > 1 - #endif // HOTENDS > 1 + #endif // HOTENDS #if HAS_HEATED_BED #ifdef BED_MINTEMP @@ -1976,7 +1991,9 @@ void Temperature::disable_all_heaters() { planner.autotemp_enabled = false; #endif - HOTEND_LOOP() setTargetHotend(0, e); + #if HOTENDS + HOTEND_LOOP() setTargetHotend(0, e); + #endif #if HAS_HEATED_BED setTargetBed(0); @@ -2238,9 +2255,11 @@ void Temperature::readings_ready() { current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach #endif - HOTEND_LOOP() temp_hotend[e].reset(); - #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - temp_hotend[1].reset(); + #if HOTENDS + HOTEND_LOOP() temp_hotend[e].reset(); + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + temp_hotend[1].reset(); + #endif #endif #if HAS_HEATED_BED @@ -2261,55 +2280,59 @@ void Temperature::readings_ready() { joystick.z.reset(); #endif - static constexpr int8_t temp_dir[] = { - #if ENABLED(HEATER_0_USES_MAX6675) - 0 - #else - TEMPDIR(0) - #endif - #if HOTENDS > 1 - #if ENABLED(HEATER_1_USES_MAX6675) - , 0 - #else - , TEMPDIR(1) - #endif - #if HOTENDS > 2 - , TEMPDIR(2) - #if HOTENDS > 3 - , TEMPDIR(3) - #if HOTENDS > 4 - , TEMPDIR(4) - #if HOTENDS > 5 - , TEMPDIR(5) - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HOTENDS > 1 - }; + #if HOTENDS - for (uint8_t e = 0; e < COUNT(temp_dir); e++) { - const int8_t tdir = temp_dir[e]; - if (tdir) { - const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp - const bool heater_on = (temp_hotend[e].target > 0 - #if ENABLED(PIDTEMP) - || temp_hotend[e].soft_pwm_amount > 0 - #endif - ); - if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e); - if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { - #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED - if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) - #endif - min_temp_error((heater_ind_t)e); - } - #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED - else - consecutive_low_temperature_error[e] = 0; + static constexpr int8_t temp_dir[] = { + #if ENABLED(HEATER_0_USES_MAX6675) + 0 + #else + TEMPDIR(0) #endif + #if HOTENDS > 1 + #if ENABLED(HEATER_1_USES_MAX6675) + , 0 + #else + , TEMPDIR(1) + #endif + #if HOTENDS > 2 + , TEMPDIR(2) + #if HOTENDS > 3 + , TEMPDIR(3) + #if HOTENDS > 4 + , TEMPDIR(4) + #if HOTENDS > 5 + , TEMPDIR(5) + #endif // HOTENDS > 5 + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + }; + + for (uint8_t e = 0; e < COUNT(temp_dir); e++) { + const int8_t tdir = temp_dir[e]; + if (tdir) { + const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp + const bool heater_on = (temp_hotend[e].target > 0 + #if ENABLED(PIDTEMP) + || temp_hotend[e].soft_pwm_amount > 0 + #endif + ); + if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e); + if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error((heater_ind_t)e); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[e] = 0; + #endif + } } - } + + #endif // HOTENDS #if HAS_HEATED_BED #if TEMPDIR(BED) < 0 @@ -2399,12 +2422,10 @@ void Temperature::isr() { static bool ADCKey_pressed = false; #endif - #if ENABLED(SLOW_PWM_HEATERS) - static uint8_t slow_pwm_count = 0; + #if HOTENDS + static SoftPWM soft_pwm_hotend[HOTENDS]; #endif - static SoftPWM soft_pwm_hotend[HOTENDS]; - #if HAS_HEATED_BED static SoftPWM soft_pwm_bed; #endif @@ -2414,40 +2435,46 @@ void Temperature::isr() { #endif #if DISABLED(SLOW_PWM_HEATERS) - constexpr uint8_t pwm_mask = - #if ENABLED(SOFT_PWM_DITHER) - _BV(SOFT_PWM_SCALE) - 1 - #else - 0 - #endif - ; + + #if HOTENDS || HAS_HEATED_BED || HAS_HEATED_CHAMBER + constexpr uint8_t pwm_mask = + #if ENABLED(SOFT_PWM_DITHER) + _BV(SOFT_PWM_SCALE) - 1 + #else + 0 + #endif + ; + #define _PWM_MOD(N,S,T) do{ \ + const bool on = S.add(pwm_mask, T.soft_pwm_amount); \ + WRITE_HEATER_##N(on); \ + }while(0) + #endif /** * Standard heater PWM modulation */ if (pwm_count_tmp >= 127) { pwm_count_tmp -= 127; - #define _PWM_MOD(N,S,T) do{ \ - const bool on = S.add(pwm_mask, T.soft_pwm_amount); \ - WRITE_HEATER_##N(on); \ - }while(0) - #define _PWM_MOD_E(N) _PWM_MOD(N,soft_pwm_hotend[N],temp_hotend[N]) - _PWM_MOD_E(0); - #if HOTENDS > 1 - _PWM_MOD_E(1); - #if HOTENDS > 2 - _PWM_MOD_E(2); - #if HOTENDS > 3 - _PWM_MOD_E(3); - #if HOTENDS > 4 - _PWM_MOD_E(4); - #if HOTENDS > 5 - _PWM_MOD_E(5); - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HOTENDS > 1 + + #if HOTENDS + #define _PWM_MOD_E(N) _PWM_MOD(N,soft_pwm_hotend[N],temp_hotend[N]) + _PWM_MOD_E(0); + #if HOTENDS > 1 + _PWM_MOD_E(1); + #if HOTENDS > 2 + _PWM_MOD_E(2); + #if HOTENDS > 3 + _PWM_MOD_E(3); + #if HOTENDS > 4 + _PWM_MOD_E(4); + #if HOTENDS > 5 + _PWM_MOD_E(5); + #endif // HOTENDS > 5 + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #endif // HOTENDS #if HAS_HEATED_BED _PWM_MOD(BED,soft_pwm_bed,temp_bed); @@ -2538,6 +2565,8 @@ void Temperature::isr() { #define _SLOW_PWM(NR,PWM,SRC) do{ PWM.count = SRC.soft_pwm_amount; _SLOW_SET(NR,PWM,(PWM.count > 0)); }while(0) #define _PWM_OFF(NR,PWM) do{ if (PWM.count < slow_pwm_count) _SLOW_SET(NR,PWM,0); }while(0) + static uint8_t slow_pwm_count = 0; + if (slow_pwm_count == 0) { #if HOTENDS @@ -2634,22 +2663,24 @@ void Temperature::isr() { slow_pwm_count++; slow_pwm_count &= 0x7F; - soft_pwm_hotend[0].dec(); - #if HOTENDS > 1 - soft_pwm_hotend[1].dec(); - #if HOTENDS > 2 - soft_pwm_hotend[2].dec(); - #if HOTENDS > 3 - soft_pwm_hotend[3].dec(); - #if HOTENDS > 4 - soft_pwm_hotend[4].dec(); - #if HOTENDS > 5 - soft_pwm_hotend[5].dec(); - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HOTENDS > 1 + #if HOTENDS + soft_pwm_hotend[0].dec(); + #if HOTENDS > 1 + soft_pwm_hotend[1].dec(); + #if HOTENDS > 2 + soft_pwm_hotend[2].dec(); + #if HOTENDS > 3 + soft_pwm_hotend[3].dec(); + #if HOTENDS > 4 + soft_pwm_hotend[4].dec(); + #if HOTENDS > 5 + soft_pwm_hotend[5].dec(); + #endif // HOTENDS > 5 + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #endif // HOTENDS #if HAS_HEATED_BED soft_pwm_bed.dec(); #endif @@ -2940,7 +2971,7 @@ void Temperature::isr() { #endif // AUTO_REPORT_TEMPERATURES - #if HAS_DISPLAY + #if HOTENDS && HAS_DISPLAY void Temperature::set_heating_message(const uint8_t e) { const bool heating = isHeatingHotend(e); #if HOTENDS > 1 diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 774935e85..22b1cd6c9 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -270,11 +270,14 @@ class Temperature { static volatile bool in_temp_isr; - static hotend_info_t temp_hotend[HOTENDS + #if HOTENDS #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) - + 1 + #define HOTEND_TEMPS (HOTENDS + 1) + #else + #define HOTEND_TEMPS HOTENDS #endif - ]; + static hotend_info_t temp_hotend[HOTEND_TEMPS]; + #endif #if HAS_HEATED_BED static bed_info_t temp_bed; @@ -349,7 +352,9 @@ class Temperature { static lpq_ptr_t lpq_ptr; #endif - static temp_range_t temp_range[HOTENDS]; + #if HOTENDS + static temp_range_t temp_range[HOTENDS]; + #endif #if HAS_HEATED_BED #if WATCH_BED @@ -417,8 +422,6 @@ class Temperature { * Instance Methods */ - Temperature(); - void init(); /** @@ -456,7 +459,9 @@ class Temperature { } #endif - static float analog_to_celsius_hotend(const int raw, const uint8_t e); + #if HOTENDS + static float analog_to_celsius_hotend(const int raw, const uint8_t e); + #endif #if HAS_HEATED_BED static float analog_to_celsius_bed(const int raw); @@ -577,19 +582,31 @@ class Temperature { FORCE_INLINE static float degHotend(const uint8_t e) { E_UNUSED(); - return temp_hotend[HOTEND_INDEX].celsius; + #if HOTENDS + return temp_hotend[HOTEND_INDEX].celsius; + #else + return 0; + #endif } #if ENABLED(SHOW_TEMP_ADC_VALUES) FORCE_INLINE static int16_t rawHotendTemp(const uint8_t e) { E_UNUSED(); - return temp_hotend[HOTEND_INDEX].raw; + #if HOTENDS + return temp_hotend[HOTEND_INDEX].raw; + #else + return 0; + #endif } #endif FORCE_INLINE static int16_t degTargetHotend(const uint8_t e) { E_UNUSED(); - return temp_hotend[HOTEND_INDEX].target; + #if HOTENDS + return temp_hotend[HOTEND_INDEX].target; + #else + return 0; + #endif } #if WATCH_HOTENDS @@ -598,52 +615,56 @@ class Temperature { static inline void start_watching_hotend(const uint8_t e=0) { UNUSED(e); } #endif - #if HAS_LCD_MENU - static inline void start_watching_E0() { start_watching_hotend(0); } - static inline void start_watching_E1() { start_watching_hotend(1); } - static inline void start_watching_E2() { start_watching_hotend(2); } - static inline void start_watching_E3() { start_watching_hotend(3); } - static inline void start_watching_E4() { start_watching_hotend(4); } - static inline void start_watching_E5() { start_watching_hotend(5); } - #endif + #if HOTENDS - static void setTargetHotend(const int16_t celsius, const uint8_t e) { - E_UNUSED(); - const uint8_t ee = HOTEND_INDEX; - #ifdef MILLISECONDS_PREHEAT_TIME - if (celsius == 0) - reset_preheat_time(ee); - else if (temp_hotend[ee].target == 0) - start_preheat_time(ee); + #if HAS_LCD_MENU + static inline void start_watching_E0() { start_watching_hotend(0); } + static inline void start_watching_E1() { start_watching_hotend(1); } + static inline void start_watching_E2() { start_watching_hotend(2); } + static inline void start_watching_E3() { start_watching_hotend(3); } + static inline void start_watching_E4() { start_watching_hotend(4); } + static inline void start_watching_E5() { start_watching_hotend(5); } #endif - #if ENABLED(AUTO_POWER_CONTROL) - powerManager.power_on(); - #endif - temp_hotend[ee].target = _MIN(celsius, temp_range[ee].maxtemp - 15); - start_watching_hotend(ee); - } - FORCE_INLINE static bool isHeatingHotend(const uint8_t e) { - E_UNUSED(); - return temp_hotend[HOTEND_INDEX].target > temp_hotend[HOTEND_INDEX].celsius; - } - - FORCE_INLINE static bool isCoolingHotend(const uint8_t e) { - E_UNUSED(); - return temp_hotend[HOTEND_INDEX].target < temp_hotend[HOTEND_INDEX].celsius; - } - - #if HAS_TEMP_HOTEND - static bool wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling=true - #if G26_CLICK_CAN_CANCEL - , const bool click_to_cancel=false + static void setTargetHotend(const int16_t celsius, const uint8_t e) { + E_UNUSED(); + const uint8_t ee = HOTEND_INDEX; + #ifdef MILLISECONDS_PREHEAT_TIME + if (celsius == 0) + reset_preheat_time(ee); + else if (temp_hotend[ee].target == 0) + start_preheat_time(ee); #endif - ); - #endif + #if ENABLED(AUTO_POWER_CONTROL) + powerManager.power_on(); + #endif + temp_hotend[ee].target = _MIN(celsius, temp_range[ee].maxtemp - 15); + start_watching_hotend(ee); + } - FORCE_INLINE static bool still_heating(const uint8_t e) { - return degTargetHotend(e) > TEMP_HYSTERESIS && ABS(degHotend(e) - degTargetHotend(e)) > TEMP_HYSTERESIS; - } + FORCE_INLINE static bool isHeatingHotend(const uint8_t e) { + E_UNUSED(); + return temp_hotend[HOTEND_INDEX].target > temp_hotend[HOTEND_INDEX].celsius; + } + + FORCE_INLINE static bool isCoolingHotend(const uint8_t e) { + E_UNUSED(); + return temp_hotend[HOTEND_INDEX].target < temp_hotend[HOTEND_INDEX].celsius; + } + + #if HAS_TEMP_HOTEND + static bool wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling=true + #if G26_CLICK_CAN_CANCEL + , const bool click_to_cancel=false + #endif + ); + #endif + + FORCE_INLINE static bool still_heating(const uint8_t e) { + return degTargetHotend(e) > TEMP_HYSTERESIS && ABS(degHotend(e) - degTargetHotend(e)) > TEMP_HYSTERESIS; + } + + #endif // HOTENDS #if HAS_HEATED_BED diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 264dd1670..1e5af33c9 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -695,11 +695,13 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { #endif // ELECTROMAGNETIC_SWITCHING_TOOLHEAD -inline void invalid_extruder_error(const uint8_t e) { - SERIAL_ECHO_START(); - SERIAL_CHAR('T'); SERIAL_ECHO(int(e)); - SERIAL_CHAR(' '); SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER); -} +#if EXTRUDERS + inline void invalid_extruder_error(const uint8_t e) { + SERIAL_ECHO_START(); + SERIAL_CHAR('T'); SERIAL_ECHO(int(e)); + SERIAL_CHAR(' '); SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER); + } +#endif #if ENABLED(DUAL_X_CARRIAGE) @@ -788,6 +790,11 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { mmu2.tool_change(new_tool); + #elif EXTRUDERS == 0 + + // Nothing to do + UNUSED(new_tool); UNUSED(no_move); + #elif EXTRUDERS < 2 UNUSED(no_move);