Merge branch 'bugfix-2.0.x' into Implement-M591-Configurable-Runout-Sensors

This commit is contained in:
InsanityAutomation
2022-04-10 15:01:53 -04:00
43 changed files with 528 additions and 306 deletions
+7 -3
View File
@@ -643,6 +643,9 @@
* for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 to autotune the model.
*/
#if ENABLED(MPCTEMP)
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash)
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
#define MPC_MAX BANG_MAX // (0..255) Current to nozzle while MPC is active.
#define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers.
@@ -671,6 +674,7 @@
#define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced.
#define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center just above the surface.
#define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position.
#endif
//===========================================================================
@@ -766,8 +770,8 @@
#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 PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
#endif
// @section extruder
@@ -1956,7 +1960,7 @@
* M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.)
*/
//#define EEPROM_SETTINGS // Persistent storage with M500 and M501
//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release!
//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release!
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
+12 -5
View File
@@ -2494,12 +2494,16 @@
#define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255
#define TOOLCHANGE_FS_FAN_TIME 10 // (seconds)
// Swap uninitialized extruder (using TOOLCHANGE_FS_PRIME_SPEED feedrate)
// (May break filament if not retracted beforehand.)
//#define TOOLCHANGE_FS_INIT_BEFORE_SWAP
// Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed
//#define TOOLCHANGE_FS_SLOW_FIRST_PRIME
// Prime on the first T0 (For other tools use TOOLCHANGE_FS_INIT_BEFORE_SWAP)
// Enable with M217 V1 before printing to avoid unwanted priming on host connect
/**
* Prime T0 the first time T0 is sent to the printer:
* [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ]
* If disabled, no priming on T0 until switching back to T0 from another extruder:
* [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ]
* Enable with M217 V1 before printing to avoid unwanted priming on host connect.
*/
//#define TOOLCHANGE_FS_PRIME_FIRST_USED
/**
@@ -3871,6 +3875,9 @@
* Auto-report temperatures with M155 S<seconds>
*/
#define AUTO_REPORT_TEMPERATURES
#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT
//#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report
#endif
/**
* Auto-report position with M154 S<seconds>
+1 -1
View File
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2022-04-05"
//#define STRING_DISTRIBUTION_DATE "2022-04-10"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
+6 -2
View File
@@ -412,7 +412,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
if (do_reset_timeout) gcode.reset_stepper_timeout(ms);
if (gcode.stepper_max_timed_out(ms)) {
SERIAL_ERROR_MSG(STR_KILL_INACTIVE_TIME, parser.command_ptr);
SERIAL_ERROR_START();
SERIAL_ECHOPGM(STR_KILL_PRE);
SERIAL_ECHOLNPGM(STR_KILL_INACTIVE_TIME, parser.command_ptr);
kill();
}
@@ -473,7 +475,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
// KILL the machine
// ----------------------------------------------------------------
if (killCount >= KILL_DELAY) {
SERIAL_ERROR_MSG(STR_KILL_BUTTON);
SERIAL_ERROR_START();
SERIAL_ECHOPGM(STR_KILL_PRE);
SERIAL_ECHOLNPGM(STR_KILL_BUTTON);
kill();
}
#endif
+21 -9
View File
@@ -199,16 +199,20 @@
#define STR_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108"
#define STR_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume"
#define STR_STOP_BLTOUCH "!! STOP called because of BLTouch error - restart with M999"
#define STR_STOP_UNHOMED "!! STOP called because of unhomed error - restart with M999"
#define STR_KILL_INACTIVE_TIME "!! KILL caused by too much inactive time - current command: "
#define STR_KILL_BUTTON "!! KILL caused by KILL button/pin"
#define STR_STOP_PRE "!! STOP called because of "
#define STR_STOP_POST " error - restart with M999"
#define STR_STOP_BLTOUCH "BLTouch"
#define STR_STOP_UNHOMED "unhomed"
#define STR_KILL_PRE "!! KILL caused by "
#define STR_KILL_INACTIVE_TIME "too much inactive time - current command: "
#define STR_KILL_BUTTON "KILL button/pin"
// temperature.cpp strings
#define STR_PID_AUTOTUNE_START "PID Autotune start"
#define STR_PID_BAD_HEATER_ID "PID Autotune failed! Bad heater id"
#define STR_PID_TEMP_TOO_HIGH "PID Autotune failed! Temperature too high"
#define STR_PID_TIMEOUT "PID Autotune failed! timeout"
#define STR_PID_AUTOTUNE "PID Autotune"
#define STR_PID_AUTOTUNE_START " start"
#define STR_PID_BAD_HEATER_ID " failed! Bad heater id"
#define STR_PID_TEMP_TOO_HIGH " failed! Temperature too high"
#define STR_PID_TIMEOUT " failed! timeout"
#define STR_BIAS " bias: "
#define STR_D_COLON " d: "
#define STR_T_MIN " min: "
@@ -219,7 +223,7 @@
#define STR_KP " Kp: "
#define STR_KI " Ki: "
#define STR_KD " Kd: "
#define STR_PID_AUTOTUNE_FINISHED "PID Autotune finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
#define STR_PID_AUTOTUNE_FINISHED " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
#define STR_PID_DEBUG " PID_DEBUG "
#define STR_PID_DEBUG_INPUT ": Input "
#define STR_PID_DEBUG_OUTPUT " Output "
@@ -228,6 +232,14 @@
#define STR_PID_DEBUG_DTERM " dTerm "
#define STR_PID_DEBUG_CTERM " cTerm "
#define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
#define STR_MPC_AUTOTUNE "MPC Autotune"
#define STR_MPC_AUTOTUNE_START " start for " STR_E
#define STR_MPC_AUTOTUNE_INTERRUPTED " interrupted!"
#define STR_MPC_AUTOTUNE_FINISHED " finished! Put the constants below into Configuration.h"
#define STR_MPC_COOLING_TO_AMBIENT "Cooling to ambient"
#define STR_MPC_HEATING_PAST_200 "Heating to over 200C"
#define STR_MPC_MEASURING_AMBIENT "Measuring ambient heatloss at "
#define STR_MPC_TEMPERATURE_ERROR "Temperature error"
#define STR_HEATER_BED "bed"
#define STR_HEATER_CHAMBER "chamber"
+4 -11
View File
@@ -111,11 +111,8 @@ bool BLTouch::deploy_proc() {
// Last attempt to DEPLOY
if (_deploy_query_alarm()) {
// The deploy might have failed or the probe is actually triggered (nozzle too low?) again
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Recovery Failed");
SERIAL_ERROR_MSG(STR_STOP_BLTOUCH); // Tell the user something is wrong, needs action
stop(); // but it's not too bad, no need to kill, allow restart
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Deploy Failed");
probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart
return true; // Tell our caller we goofed in case he cares to know
}
}
@@ -153,12 +150,8 @@ bool BLTouch::stow_proc() {
// But one more STOW will catch that
// Last attempt to STOW
if (_stow_query_alarm()) { // so if there is now STILL an ALARM condition:
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Recovery Failed");
SERIAL_ERROR_MSG(STR_STOP_BLTOUCH); // Tell the user something is wrong, needs action
stop(); // but it's not too bad, no need to kill, allow restart
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Stow Failed");
probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart
return true; // Tell our caller we goofed in case he cares to know
}
}
+3 -2
View File
@@ -681,8 +681,9 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
// If resume_position is negative
if (resume_position.e < 0) unscaled_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
#if ADVANCED_PAUSE_RESUME_PRIME != 0
unscaled_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE));
#ifdef ADVANCED_PAUSE_RESUME_PRIME
if (ADVANCED_PAUSE_RESUME_PRIME != 0)
unscaled_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE));
#endif
// Now all extrusion positions are resumed and ready to be confirmed
+1 -1
View File
@@ -375,7 +375,7 @@ void GcodeSuite::G28() {
homeZZ = homeZ,
homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME),
homeK = needK || parser.seen_test(AXIS6_NAME), homeU = needU || parser.seen_test(AXIS7_NAME),
homeV = needV || parser.seen_test(AXIS8_NAME), homeW = needW || parser.seen_test(AXIS9_NAME),
homeV = needV || parser.seen_test(AXIS8_NAME), homeW = needW || parser.seen_test(AXIS9_NAME)
),
home_all = NUM_AXIS_GANG( // Home-all if all or none are flagged
homeX == homeX, && homeY == homeX, && homeZ == homeX,
+30 -30
View File
@@ -34,31 +34,31 @@
#include "../../MarlinCore.h" // for SP_X_STR, etc.
/**
* M217 - Set SINGLENOZZLE toolchange parameters
* M217 - Set toolchange parameters
*
* // Tool change command
* Q Prime active tool and exit
*
* // Tool change settings
* S[linear] Swap length
* B[linear] Extra Swap length
* E[linear] Prime length
* P[linear/m] Prime speed
* R[linear/m] Retract speed
* U[linear/m] UnRetract speed
* V[linear] 0/1 Enable auto prime first extruder used
* W[linear] 0/1 Enable park & Z Raise
* X[linear] Park X (Requires TOOLCHANGE_PARK)
* Y[linear] Park Y (Requires TOOLCHANGE_PARK)
* I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4)
* J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5)
* K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6)
* C[linear] Park U (Requires TOOLCHANGE_PARK and NUM_AXES >= 7)
* H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8)
* O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9)
* Z[linear] Z Raise
* F[linear] Fan Speed 0-255
* G[linear/s] Fan time
* S[linear] Swap length
* B[linear] Extra Swap resume length
* E[linear] Extra Prime length (as used by M217 Q)
* P[linear/min] Prime speed
* R[linear/min] Retract speed
* U[linear/min] UnRetract speed
* V[linear] 0/1 Enable auto prime first extruder used
* W[linear] 0/1 Enable park & Z Raise
* X[linear] Park X (Requires TOOLCHANGE_PARK)
* Y[linear] Park Y (Requires TOOLCHANGE_PARK)
* I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4)
* J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5)
* K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6)
* C[linear] Park U (Requires TOOLCHANGE_PARK and NUM_AXES >= 7)
* H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8)
* O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9)
* Z[linear] Z Raise
* F[speed] Fan Speed 0-255
* D[seconds] Fan time
*
* Tool migration settings
* A[0|1] Enable auto-migration on runout
@@ -82,8 +82,8 @@ void GcodeSuite::M217() {
if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); }
if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); }
#if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN
if (parser.seenval('F')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_speed = constrain(v, 0, 255); }
if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_time = constrain(v, 1, 30); }
if (parser.seenval('F')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_speed = constrain(v, 0, 255); }
if (parser.seenval('D')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_time = constrain(v, 1, 30); }
#endif
#endif
@@ -171,7 +171,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
" U", LINEAR_UNIT(toolchange_settings.unretract_speed),
" F", toolchange_settings.fan_speed,
" G", toolchange_settings.fan_time);
" D", toolchange_settings.fan_time);
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
SERIAL_ECHOPGM(" A", migration.automode);
@@ -186,13 +186,13 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
#endif
#if SECONDARY_AXES >= 1
, LIST_N(DOUBLE(SECONDARY_AXES),
PSTR(" I"), I_AXIS_UNIT(toolchange_settings.change_point.i),
PSTR(" J"), J_AXIS_UNIT(toolchange_settings.change_point.j),
PSTR(" K"), K_AXIS_UNIT(toolchange_settings.change_point.k),
SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u),
PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v),
PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w),
, LIST_N(DOUBLE(SECONDARY_AXES)
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
)
#endif
);
+1
View File
@@ -71,6 +71,7 @@ void GcodeSuite::M303() {
case H_CHAMBER: default_temp = PREHEAT_1_TEMP_CHAMBER; break;
#endif
default:
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_BAD_HEATER_ID);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM));
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_BAD_EXTRUDER_NUM));
+1 -11
View File
@@ -56,17 +56,7 @@ void GcodeSuite::M306() {
return;
}
HOTEND_LOOP() {
SERIAL_ECHOLNPGM("MPC constants for hotend ", e);
MPC_t& constants = thermalManager.temp_hotend[e].constants;
SERIAL_ECHOLNPGM("Heater power: ", constants.heater_power);
SERIAL_ECHOLNPGM("Heatblock heat capacity: ", constants.block_heat_capacity);
SERIAL_ECHOLNPAIR_F("Sensor responsivness: ", constants.sensor_responsiveness, 4);
SERIAL_ECHOLNPAIR_F("Ambient heat transfer coeff. (no fan): ", constants.ambient_xfer_coeff_fan0, 4);
#if ENABLED(MPC_INCLUDE_FAN)
SERIAL_ECHOLNPAIR_F("Ambient heat transfer coeff. (full fan): ", constants.ambient_xfer_coeff_fan0 + constants.fan255_adjustment, 4);
#endif
}
M306_report(true);
}
void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
+2 -2
View File
@@ -524,7 +524,7 @@
#define HAS_LCDPRINT 1
#endif
#if ANY(HAS_DISPLAY, HAS_DWIN_E3V2, GLOBAL_STATUS_MESSAGE)
#if ANY(HAS_DISPLAY, HAS_DWIN_E3V2)
#define HAS_STATUS_MESSAGE 1
#endif
@@ -712,7 +712,7 @@
* Number of Primary Linear Axes (e.g., XYZ)
* X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4)
*/
#if HAS_I_AXIS
#if NUM_AXES >= 3
#define PRIMARY_LINEAR_AXES 3
#else
#define PRIMARY_LINEAR_AXES NUM_AXES
+15 -13
View File
@@ -390,6 +390,8 @@
#error "ENDSTOP_NOISE_FILTER is now ENDSTOP_NOISE_THRESHOLD [2-7]."
#elif defined(RETRACT_ZLIFT)
#error "RETRACT_ZLIFT is now RETRACT_ZRAISE."
#elif defined(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
#error "TOOLCHANGE_FS_INIT_BEFORE_SWAP is now TOOLCHANGE_FS_SLOW_FIRST_PRIME."
#elif defined(TOOLCHANGE_PARK_ZLIFT) || defined(TOOLCHANGE_UNPARK_ZLIFT)
#error "TOOLCHANGE_PARK_ZLIFT and TOOLCHANGE_UNPARK_ZLIFT are now TOOLCHANGE_ZRAISE."
#elif defined(SINGLENOZZLE_TOOLCHANGE_ZRAISE)
@@ -2503,17 +2505,17 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
* FYSETC LCD Requirements
*/
#if EITHER(FYSETC_242_OLED_12864, FYSETC_MINI_12864_2_1)
#ifndef NEO_RGB
#define NEO_RGB 123
#ifndef NEO_GRB
#define NEO_GRB 123
#define FAUX_RGB 1
#endif
#if defined(NEOPIXEL_TYPE) && NEOPIXEL_TYPE != NEO_RGB
#error "Your FYSETC Mini Panel requires NEOPIXEL_TYPE to be NEO_RGB."
#if defined(NEOPIXEL_TYPE) && NEOPIXEL_TYPE != NEO_GRB
#error "Your FYSETC Mini Panel requires NEOPIXEL_TYPE to be NEO_GRB."
#elif defined(NEOPIXEL_PIXELS) && NEOPIXEL_PIXELS < 3
#error "Your FYSETC Mini Panel requires NEOPIXEL_PIXELS >= 3."
#endif
#if FAUX_RGB
#undef NEO_RGB
#undef NEO_GRB
#undef FAUX_RGB
#endif
#elif EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) && !DISABLED(RGB_LED)
@@ -3019,10 +3021,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#if ENABLED(DWIN_CREALITY_LCD)
#if DISABLED(SDSUPPORT)
#error "DWIN_CREALITY_LCD requires SDSUPPORT to be enabled."
#elif ENABLED(PID_EDIT_MENU)
#error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU."
#elif ENABLED(PID_AUTOTUNE_MENU)
#error "DWIN_CREALITY_LCD does not support PID_AUTOTUNE_MENU."
#elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU)
#error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
#elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)
#error "DWIN_CREALITY_LCD does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU."
#elif ENABLED(LEVEL_BED_CORNERS)
#error "DWIN_CREALITY_LCD does not support LEVEL_BED_CORNERS."
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
@@ -3031,10 +3033,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#elif ENABLED(DWIN_LCD_PROUI)
#if DISABLED(SDSUPPORT)
#error "DWIN_LCD_PROUI requires SDSUPPORT to be enabled."
#elif ENABLED(PID_EDIT_MENU)
#error "DWIN_LCD_PROUI does not support PID_EDIT_MENU."
#elif ENABLED(PID_AUTOTUNE_MENU)
#error "DWIN_LCD_PROUI does not support PID_AUTOTUNE_MENU."
#elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU)
#error "DWIN_LCD_PROUI does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
#elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)
#error "DWIN_LCD_PROUI does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU."
#elif ENABLED(LEVEL_BED_CORNERS)
#error "DWIN_LCD_PROUI does not support LEVEL_BED_CORNERS."
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
+1 -1
View File
@@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2022-04-05"
#define STRING_DISTRIBUTION_DATE "2022-04-10"
#endif
/**
-4
View File
@@ -235,7 +235,6 @@ void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis,
// rlimit: To limit the drawn string length
void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const char * const string, uint16_t rlimit/*=0xFFFF*/) {
DWIN_Draw_Rectangle(1, bColor, x, y, x + (fontWidth(size) * strlen_P(string)), y + fontHeight(size));
DWIN_UpdateLCD();
constexpr uint8_t widthAdjust = 0;
size_t i = 0;
DWIN_Byte(i, 0x11);
@@ -250,7 +249,6 @@ void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor,
DWIN_Word(i, y);
DWIN_Text(i, string, rlimit);
DWIN_Send(i);
DWIN_UpdateLCD();
}
// Draw a positive integer
@@ -297,7 +295,6 @@ void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t
#endif
DWIN_Send(i);
DWIN_UpdateLCD();
}
// Draw a floating point number
@@ -332,7 +329,6 @@ void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_
DWIN_Byte(i, fvalue[0]);
*/
DWIN_Send(i);
DWIN_UpdateLCD();
}
// Draw a floating point number
@@ -181,7 +181,6 @@ void MarlinUI::draw_status_message(const bool blink) {
dwin_font.solid = true;
dwin_font.fg = Color_White;
dwin_font.bg = Color_Bg_Black;
DWIN_Draw_Box(1, Color_Bg_Black, 0, (LCD_PIXEL_HEIGHT - (STAT_FONT_HEIGHT) - 1), 272, STAT_FONT_HEIGHT + 1);
lcd_moveto_xy(0, LCD_PIXEL_HEIGHT - (STAT_FONT_HEIGHT) - 1);
constexpr uint8_t max_status_chars = (LCD_PIXEL_WIDTH) / (STAT_FONT_WIDTH);
@@ -45,7 +45,7 @@
*/
#define __DECL_DATA_IF_INCLUDED(CLASS) struct CLASS ## Data CLASS ;
#define _DECL_DATA_IF_INCLUDED(CLASS) __DECL_DATA_IF_INCLUDED(CLASS)
#define DECL_DATA_IF_INCLUDED(HEADER) TERN(HEADER, _DECL_DATA_IF_INCLUDED(HEADER ## _CLASS), )
#define DECL_DATA_IF_INCLUDED(HEADER) TERN_(HEADER, _DECL_DATA_IF_INCLUDED(HEADER ## _CLASS))
union screen_data_t {
DECL_DATA_IF_INCLUDED(FTDI_INTERFACE_SETTINGS_SCREEN)
@@ -74,7 +74,7 @@ void lv_draw_level_settings() {
#if HAS_BED_PROBE
lv_screen_menu_item(scr, machine_menu.LevelingAutoZoffsetConf, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_LEVEL_ZOFFSET, 2);
#if ENABLED(PROBE_OFFSET_WIZARD)
lv_screen_menu_item(scr, machine_menu.LevelingZoffsetWizard, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_Z_OFFSET_WIZARD, 3);
lv_screen_menu_item(scr, machine_menu.LevelingZoffsetTitle, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_Z_OFFSET_WIZARD, 3);
#endif
#endif
lv_big_button_create(scr, "F:/bmp_back70x40.bin", common_menu.text_back, PARA_UI_BACK_POS_X + 10, PARA_UI_BACK_POS_Y, event_handler, ID_LEVEL_RETURN, true);
+8
View File
@@ -350,6 +350,14 @@ namespace Language_en {
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed. Bad extruder.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed. Temperature too high.");
LSTR MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout.");
LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Testing heat loss");
LSTR MSG_MPC_AUTOTUNE = _UxGT("MPC Autotune");
LSTR MSG_MPC_EDIT = _UxGT("Edit * MPC");
LSTR MSG_MPC_POWER_E = _UxGT("Power *");
LSTR MSG_MPC_BLOCK_HEAT_CAPACITY_E = _UxGT("Block C *");
LSTR MSG_SENSOR_RESPONSIVENESS_E = _UxGT("Sensor res *");
LSTR MSG_MPC_AMBIENT_XFER_COEFF_E = _UxGT("Ambient h *");
LSTR MSG_MPC_AMBIENT_XFER_COEFF_FAN255_E= _UxGT("Amb. h fan *");
LSTR MSG_SELECT = _UxGT("Select");
LSTR MSG_SELECT_E = _UxGT("Select *");
LSTR MSG_ACC = _UxGT("Accel");
+3 -2
View File
@@ -55,6 +55,7 @@ namespace Language_zh_CN {
LSTR MSG_DISABLE_STEPPERS = _UxGT("关闭步进电机"); // "Disable steppers"
LSTR MSG_DEBUG_MENU = _UxGT("调试菜单"); // "Debug Menu"
LSTR MSG_PROGRESS_BAR_TEST = _UxGT("进度条测试"); // "Progress Bar Test"
LSTR MSG_HOMING = _UxGT("回原点");
LSTR MSG_AUTO_HOME = _UxGT("自动回原点"); // "Auto home"
LSTR MSG_AUTO_HOME_X = _UxGT("回X原位"); // "Home X"
LSTR MSG_AUTO_HOME_Y = _UxGT("回Y原位"); // "Home Y"
@@ -93,8 +94,8 @@ namespace Language_zh_CN {
LSTR MSG_SPINDLE_MENU = _UxGT("主轴控制");
LSTR MSG_SPINDLE_POWER = _UxGT("主轴电源");
LSTR MSG_SPINDLE_REVERSE = _UxGT("主轴反转");
LSTR MSG_SWITCH_PS_ON = _UxGT("电源打开"); // "Switch power on"
LSTR MSG_SWITCH_PS_OFF = _UxGT("电源关闭"); // "Switch power off"
LSTR MSG_SWITCH_PS_ON = _UxGT("开启电源"); // "Switch power on"
LSTR MSG_SWITCH_PS_OFF = _UxGT("关闭电源"); // "Switch power off"
LSTR MSG_EXTRUDE = _UxGT("挤出"); // "Extrude"
LSTR MSG_RETRACT = _UxGT("回抽"); // "Retract"
LSTR MSG_MOVE_AXIS = _UxGT("移动轴"); // "Move axis"
+54 -4
View File
@@ -255,7 +255,7 @@ void menu_backlash();
// Helpers for editing PID Ki & Kd values
// grab the PID value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_i(const uint8_t e) {
void copy_and_scalePID_i(const int8_t e) {
switch (e) {
#if ENABLED(PIDTEMPBED)
case H_BED: thermalManager.temp_bed.pid.Ki = scalePID_i(raw_Ki); break;
@@ -271,7 +271,7 @@ void menu_backlash();
break;
}
}
void copy_and_scalePID_d(const uint8_t e) {
void copy_and_scalePID_d(const int8_t e) {
switch (e) {
#if ENABLED(PIDTEMPBED)
case H_BED: thermalManager.temp_bed.pid.Kd = scalePID_d(raw_Kd); break;
@@ -289,7 +289,7 @@ void menu_backlash();
}
#endif
#if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) || EITHER(PID_AUTOTUNE_MENU, PID_EDIT_MENU)
#if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) || ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU, MPC_AUTOTUNE_MENU, MPC_EDIT_MENU)
#define SHOW_MENU_ADVANCED_TEMPERATURE 1
#endif
@@ -298,9 +298,20 @@ void menu_backlash();
//
#if SHOW_MENU_ADVANCED_TEMPERATURE
#if ENABLED(MPC_EDIT_MENU)
#define MPC_EDIT_DEFS(N) \
MPC_t &c = thermalManager.temp_hotend[N].constants; \
TERN(MPC_INCLUDE_FAN, editable.decimal = c.ambient_xfer_coeff_fan0 + c.fan255_adjustment)
#endif
void menu_advanced_temperature() {
#if ENABLED(MPC_EDIT_MENU) && !HAS_MULTI_HOTEND
MPC_EDIT_DEFS(0);
#endif
START_MENU();
BACK_ITEM(MSG_ADVANCED_SETTINGS);
//
// Autotemp, Min, Max, Fact
//
@@ -370,10 +381,49 @@ void menu_backlash();
HOTEND_PID_EDIT_MENU_ITEMS(0);
#if ENABLED(PID_PARAMS_PER_HOTEND)
REPEAT_S(1, HOTENDS, HOTEND_PID_EDIT_MENU_ITEMS)
REPEAT_S(1, HOTENDS, HOTEND_PID_EDIT_MENU_ITEMS);
#endif
#endif
#if ENABLED(MPC_EDIT_MENU)
#define _MPC_EDIT_ITEMS(N) \
EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_POWER_E, &c.heater_power, 1, 200); \
EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_BLOCK_HEAT_CAPACITY_E, &c.block_heat_capacity, 0, 40); \
EDIT_ITEM_FAST_N(float43, N, MSG_SENSOR_RESPONSIVENESS_E, &c.sensor_responsiveness, 0, 1); \
EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_E, &c.ambient_xfer_coeff_fan0, 0, 1)
#if ENABLED(MPC_INCLUDE_FAN)
#define MPC_EDIT_ITEMS(N) \
_MPC_EDIT_ITEMS(N); \
EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_FAN255_E, &editable.decimal, 0, 1, []{ \
c.fan255_adjustment = editable.decimal - c.ambient_xfer_coeff_fan0; \
})
#else
#define MPC_EDIT_ITEMS _MPC_EDIT_ITEMS
#endif
#if HAS_MULTI_HOTEND
auto mpc_edit_hotend = [&](const uint8_t e) {
MPC_EDIT_DEFS(e);
START_MENU();
BACK_ITEM(MSG_TEMPERATURE);
MPC_EDIT_ITEMS(e);
END_MENU();
};
#define MPC_ENTRY(N) SUBMENU_N(N, MSG_MPC_EDIT, []{ mpc_edit_hotend(MenuItemBase::itemIndex); });
#else
#define MPC_ENTRY MPC_EDIT_ITEMS
#endif
REPEAT(HOTENDS, MPC_ENTRY);
#endif // MPC_EDIT_MENU
#if ENABLED(MPC_AUTOTUNE_MENU)
ACTION_ITEM(MSG_MPC_AUTOTUNE, []{ queue.inject(F("M306 T")); ui.return_to_status(); });
#endif
#if ENABLED(PIDTEMPBED)
#if ENABLED(PID_EDIT_MENU)
_PID_EDIT_ITEMS_TMPL(H_BED, thermalManager.temp_bed);
+2 -2
View File
@@ -122,8 +122,8 @@ void menu_advanced_settings();
EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_UNRETRACT_SPEED, &toolchange_settings.unretract_speed, 10, 5400);
EDIT_ITEM(float3, MSG_FILAMENT_PURGE_LENGTH, &toolchange_settings.extra_prime, 0, max_extrude);
EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_PRIME_SPEED, &toolchange_settings.prime_speed, 10, 5400);
EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255);
EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30);
EDIT_ITEM_FAST(uint8, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255);
EDIT_ITEM_FAST(uint8, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30);
#endif
EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10);
END_MENU();
+1 -1
View File
@@ -1166,7 +1166,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
#if ENABLED(MESH_BED_LEVELING)
mbl.line_to_destination(scaled_fr_mm_s);
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
bilinear_line_to_destination(scaled_fr_mm_s);
bbl.line_to_destination(scaled_fr_mm_s);
#endif
return true;
}
+1 -1
View File
@@ -592,7 +592,7 @@ class Planner {
*/
static float fade_scaling_factor_for_z(const_float_t rz) {
static float z_fade_factor = 1;
if (!z_fade_height) return 1;
if (!z_fade_height || rz <= 0) return 1;
if (rz >= z_fade_height) return 0;
if (last_fade_z != rz) {
last_fade_z = rz;
+18 -7
View File
@@ -415,6 +415,21 @@ FORCE_INLINE void probe_specific_action(const bool deploy) {
#endif
/**
* Print an error and stop()
*/
void Probe::probe_error_stop() {
SERIAL_ERROR_START();
SERIAL_ECHOPGM(STR_STOP_PRE);
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
SERIAL_ECHOPGM(STR_STOP_UNHOMED);
#elif ENABLED(BLTOUCH)
SERIAL_ECHOPGM(STR_STOP_BLTOUCH);
#endif
SERIAL_ECHOLNPGM(STR_STOP_POST);
stop();
}
/**
* Attempt to deploy or stow the probe
*
@@ -443,8 +458,7 @@ bool Probe::set_deployed(const bool deploy) {
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
if (homing_needed_error(TERN_(Z_PROBE_SLED, _BV(X_AXIS)))) {
SERIAL_ERROR_MSG(STR_STOP_UNHOMED);
stop();
probe_error_stop();
return true;
}
#endif
@@ -484,15 +498,12 @@ bool Probe::set_deployed(const bool deploy) {
}
/**
* @brief Used by run_z_probe to do a single Z probe move.
* @brief Move down until the probe triggers or the low limit is reached
* Used by run_z_probe to do a single Z probe move.
*
* @param z Z destination
* @param fr_mm_s Feedrate in mm/s
* @return true to indicate an error
*/
/**
* @brief Move down until the probe triggers or the low limit is reached
*
* @details Used by run_z_probe to get each bed Z height measurement.
* Sets current_position.z to the height where the probe triggered
+2
View File
@@ -78,6 +78,8 @@ public:
static void preheat_for_probing(const celsius_t hotend_temp, const celsius_t bed_temp);
#endif
static void probe_error_stop();
static bool set_deployed(const bool deploy);
#if IS_KINEMATIC
+115 -71
View File
@@ -141,8 +141,12 @@
#endif
#endif
#if EITHER(MPCTEMP, PID_EXTRUSION_SCALING)
#if ENABLED(MPCTEMP)
#include <math.h>
#include "probe.h"
#endif
#if EITHER(MPCTEMP, PID_EXTRUSION_SCALING)
#include "stepper.h"
#endif
@@ -632,6 +636,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START));
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
@@ -639,6 +644,7 @@ volatile bool Temperature::raw_temps_ready = false;
return;
}
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_START);
disable_all_heaters();
@@ -654,10 +660,11 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false);
// PID Tuning loop
wait_for_heatup = true; // Can be interrupted with M108
LCD_MESSAGE(MSG_HEATING);
while (wait_for_heatup) {
// PID Tuning loop
wait_for_heatup = true;
while (wait_for_heatup) { // Can be interrupted with M108
const millis_t ms = millis();
@@ -723,6 +730,7 @@ volatile bool Temperature::raw_temps_ready = false;
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
#endif
if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
@@ -765,11 +773,13 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TUNING_TIMEOUT));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT)));
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
break;
}
if (cycles > ncycles && cycles > 2) {
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_FINISHED);
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)));
@@ -858,34 +868,65 @@ volatile bool Temperature::raw_temps_ready = false;
if (ELAPSED(ms, next_report_ms)) {
next_report_ms += 1000UL;
SERIAL_ECHOLNPGM("Temperature ", current_temp);
print_heater_states(active_extruder);
SERIAL_EOL();
}
hal.idletask();
TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
if (!wait_for_heatup) {
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_INTERRUPTED);
return false;
}
return true;
};
SERIAL_ECHOLNPGM("Measuring MPC constants for E", active_extruder);
MPCHeaterInfo& hotend = temp_hotend[active_extruder];
MPC_t& constants = hotend.constants;
struct OnExit {
~OnExit() {
wait_for_heatup = false;
// move to center of bed, just above bed height and cool with max fan
SERIAL_ECHOLNPGM("Moving to tuning position");
TERN_(HAS_FAN, zero_fan_speeds());
ui.reset_status();
temp_hotend[active_extruder].target = 0.0f;
temp_hotend[active_extruder].soft_pwm_amount = 0;
#if HAS_FAN
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0);
planner.sync_fan_speeds(fan_speed);
#endif
do_z_clearance(MPC_TUNING_END_Z);
}
} on_exit;
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_START, active_extruder);
MPCHeaterInfo &hotend = temp_hotend[active_extruder];
MPC_t &constants = hotend.constants;
// Move to center of bed, just above bed height and cool with max fan
disable_all_heaters();
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255));
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
#if HAS_FAN
zero_fan_speeds();
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
planner.sync_fan_speeds(fan_speed);
#endif
gcode.home_all_axes(true);
const xyz_pos_t tuningpos = MPC_TUNING_POS;
do_blocking_move_to(tuningpos);
SERIAL_ECHOLNPGM("Cooling to ambient");
SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT);
LCD_MESSAGE(MSG_COOLING);
millis_t ms = millis(), next_report_ms = ms, next_test_ms = ms + 10000UL;
celsius_float_t current_temp = degHotend(active_extruder),
ambient_temp = current_temp;
wait_for_heatup = true; // Can be interrupted with M108
while (wait_for_heatup) {
housekeeping(ms, current_temp, next_report_ms);
wait_for_heatup = true;
for (;;) { // Can be interrupted with M108
if (!housekeeping(ms, current_temp, next_report_ms)) return;
if (ELAPSED(ms, next_test_ms)) {
if (current_temp >= ambient_temp) {
@@ -896,27 +937,31 @@ volatile bool Temperature::raw_temps_ready = false;
next_test_ms += 10000UL;
}
}
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0));
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
#if HAS_FAN
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0);
planner.sync_fan_speeds(fan_speed);
#endif
hotend.modeled_ambient_temp = ambient_temp;
SERIAL_ECHOLNPGM("Heating to 200C");
SERIAL_ECHOLNPGM(STR_MPC_HEATING_PAST_200);
LCD_MESSAGE(MSG_HEATING);
hotend.target = 200.0f; // So M105 looks nice
hotend.soft_pwm_amount = MPC_MAX >> 1;
const millis_t heat_start_time = ms;
next_test_ms = ms;
const millis_t heat_start_time = next_test_ms = ms;
celsius_float_t temp_samples[16];
uint8_t sample_count = 0;
uint16_t sample_distance = 1;
float t1_time = 0;
while (wait_for_heatup) {
housekeeping(ms, current_temp, next_report_ms);
for (;;) { // Can be interrupted with M108
if (!housekeeping(ms, current_temp, next_report_ms)) return;
if (ELAPSED(ms, next_test_ms)) {
// record samples between 100C and 200C
// Record samples between 100C and 200C
if (current_temp >= 100.0f) {
// if there are too many samples, space them more widely
// If there are too many samples, space them more widely
if (sample_count == COUNT(temp_samples)) {
for (uint8_t i = 0; i < COUNT(temp_samples) / 2; i++)
temp_samples[i] = temp_samples[i*2];
@@ -935,13 +980,13 @@ volatile bool Temperature::raw_temps_ready = false;
}
hotend.soft_pwm_amount = 0;
// calculate physical constants from three equally spaced samples
// Calculate physical constants from three equally-spaced samples
sample_count = (sample_count + 1) / 2 * 2 - 1;
const float t1 = temp_samples[0],
t2 = temp_samples[(sample_count - 1) >> 1],
t3 = temp_samples[sample_count - 1],
asymp_temp = (t2 * t2 - t1 * t3) / (2 * t2 - t1 - t3),
block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / (sample_distance * (sample_count >> 1));
t3 = temp_samples[sample_count - 1];
float asymp_temp = (t2 * t2 - t1 * t3) / (2 * t2 - t1 - t3),
block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / (sample_distance * (sample_count >> 1));
constants.ambient_xfer_coeff_fan0 = constants.heater_power * MPC_MAX / 255 / (asymp_temp - ambient_temp);
constants.fan255_adjustment = 0.0f;
@@ -951,14 +996,14 @@ volatile bool Temperature::raw_temps_ready = false;
hotend.modeled_block_temp = asymp_temp + (ambient_temp - asymp_temp) * exp(-block_responsiveness * (ms - heat_start_time) / 1000.0f);
hotend.modeled_sensor_temp = current_temp;
// let the system stabilise under MPC control then get a better measure of ambient loss without and with fan
SERIAL_ECHOLNPGM("Measuring ambient heatloss at target ", hotend.modeled_block_temp);
// Allow the system to stabilize under MPC, then get a better measure of ambient loss with and without fan
SERIAL_ECHOLNPGM(STR_MPC_MEASURING_AMBIENT, hotend.modeled_block_temp);
LCD_MESSAGE(MSG_MPC_MEASURING_AMBIENT);
hotend.target = hotend.modeled_block_temp;
next_test_ms = ms + MPC_dT * 1000;
constexpr millis_t settle_time = 20000UL,
test_length = 20000UL;
constexpr millis_t settle_time = 20000UL, test_duration = 20000UL;
millis_t settle_end_ms = ms + settle_time,
test_end_ms = settle_end_ms + test_length;
test_end_ms = settle_end_ms + test_duration;
float total_energy_fan0 = 0.0f;
#if HAS_FAN
bool fan0_done = false;
@@ -966,22 +1011,20 @@ volatile bool Temperature::raw_temps_ready = false;
#endif
float last_temp = current_temp;
while (wait_for_heatup) {
housekeeping(ms, current_temp, next_report_ms);
for (;;) { // Can be interrupted with M108
if (!housekeeping(ms, current_temp, next_report_ms)) return;
if (ELAPSED(ms, next_test_ms)) {
// use MPC to control the temperature, let it settle for 30s and then track power output for 10s
hotend.soft_pwm_amount = (int)get_pid_output_hotend(active_extruder) >> 1;
if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms) && TERN1(HAS_FAN, !fan0_done))
total_energy_fan0 += constants.heater_power * hotend.soft_pwm_amount / 127 * MPC_dT + (last_temp - current_temp) * constants.block_heat_capacity;
#if HAS_FAN
else if (ELAPSED(ms, test_end_ms) && !fan0_done) {
SERIAL_ECHOLNPGM("Measuring ambient heatloss with full fan");
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
planner.sync_fan_speeds(fan_speed);
settle_end_ms = ms + settle_time;
test_end_ms = settle_end_ms + test_length;
test_end_ms = settle_end_ms + test_duration;
fan0_done = true;
}
else if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms))
@@ -993,31 +1036,29 @@ volatile bool Temperature::raw_temps_ready = false;
next_test_ms += MPC_dT * 1000;
}
if (!WITHIN(current_temp, hotend.target - 15.0f, hotend.target + 15.0f)) {
SERIAL_ECHOLNPGM("Temperature error while measuring ambient loss");
if (!WITHIN(current_temp, t3 - 15.0f, hotend.target + 15.0f)) {
SERIAL_ECHOLNPGM(STR_MPC_TEMPERATURE_ERROR);
break;
}
}
const float power_fan0 = total_energy_fan0 * 1000 / test_length;
const float power_fan0 = total_energy_fan0 * 1000 / test_duration;
constants.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
#if HAS_FAN
const float power_fan255 = total_energy_fan255 * 1000 / test_length,
const float power_fan255 = total_energy_fan255 * 1000 / test_duration,
ambient_xfer_coeff_fan255 = power_fan255 / (hotend.target - ambient_temp);
constants.fan255_adjustment = ambient_xfer_coeff_fan255 - constants.ambient_xfer_coeff_fan0;
#endif
hotend.target = 0.0f;
hotend.soft_pwm_amount = 0;
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0));
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
// Calculate a new and better asymptotic temperature and re-evaluate the other constants
asymp_temp = ambient_temp + constants.heater_power / constants.ambient_xfer_coeff_fan0;
block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / (sample_distance * (sample_count >> 1));
constants.block_heat_capacity = constants.ambient_xfer_coeff_fan0 / block_responsiveness;
constants.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
if (!wait_for_heatup) SERIAL_ECHOLNPGM("Test was interrupted");
wait_for_heatup = false;
SERIAL_ECHOLNPGM("Done");
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_FINISHED);
/* <-- add a slash to enable
SERIAL_ECHOLNPGM("t1_time ", t1_time);
@@ -1369,12 +1410,12 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
#endif
#elif ENABLED(MPCTEMP)
MPCHeaterInfo& hotend = temp_hotend[ee];
MPC_t& constants = hotend.constants;
MPCHeaterInfo &hotend = temp_hotend[ee];
MPC_t &constants = hotend.constants;
// At startup, initialize modeled temperatures
if (isnan(hotend.modeled_block_temp)) {
hotend.modeled_ambient_temp = min(30.0f, hotend.celsius); // cap initial value at reasonable max room temperature of 30C
hotend.modeled_ambient_temp = min(30.0f, hotend.celsius); // Cap initial value at reasonable max room temperature of 30C
hotend.modeled_block_temp = hotend.modeled_sensor_temp = hotend.celsius;
}
@@ -1395,16 +1436,16 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
const int32_t e_position = stepper.position(E_AXIS);
const float e_speed = (e_position - mpc_e_position) * planner.mm_per_step[E_AXIS] / MPC_dT;
// the position can appear to make big jumps when, e.g. homing
// The position can appear to make big jumps when, e.g. homing
if (fabs(e_speed) > planner.settings.max_feedrate_mm_s[E_AXIS])
mpc_e_position = e_position;
else if (e_speed > 0.0f) { // ignore retract/recover moves
else if (e_speed > 0.0f) { // Ignore retract/recover moves
ambient_xfer_coeff += e_speed * FILAMENT_HEAT_CAPACITY_PERMM;
mpc_e_position = e_position;
}
}
// update the modeled temperatures
// Update the modeled temperatures
float blocktempdelta = hotend.soft_pwm_amount * constants.heater_power * (MPC_dT / 127) / constants.block_heat_capacity;
blocktempdelta += (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff * MPC_dT / constants.block_heat_capacity;
hotend.modeled_block_temp += blocktempdelta;
@@ -1418,18 +1459,18 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
hotend.modeled_block_temp += delta_to_apply;
hotend.modeled_sensor_temp += delta_to_apply;
// only correct ambient when close to steady state (output power is not clipped or asymptotic temperature is reached)
// Only correct ambient when close to steady state (output power is not clipped or asymptotic temperature is reached)
if (WITHIN(hotend.soft_pwm_amount, 1, 126) || fabs(blocktempdelta + delta_to_apply) < (MPC_STEADYSTATE * MPC_dT))
hotend.modeled_ambient_temp += delta_to_apply > 0.f ? max(delta_to_apply, MPC_MIN_AMBIENT_CHANGE * MPC_dT) : min(delta_to_apply, -MPC_MIN_AMBIENT_CHANGE * MPC_dT);
float power = 0.0;
if (hotend.target != 0 && TERN1(HEATER_IDLE_HANDLER, !heater_idle[ee].timed_out)) {
// plan power level to get to target temperature in 2 seconds
// Plan power level to get to target temperature in 2 seconds
power = (hotend.target - hotend.modeled_block_temp) * constants.block_heat_capacity / 2.0f;
power -= (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff;
}
float pid_output = power * 254.0f / constants.heater_power + 1.0f; // ensure correct quantization into a range of 0 to 127
float pid_output = power * 254.0f / constants.heater_power + 1.0f; // Ensure correct quantization into a range of 0 to 127
pid_output = constrain(pid_output, 0, MPC_MAX);
/* <-- add a slash to enable
@@ -2075,7 +2116,7 @@ void Temperature::manage_heater() {
- (t.beta_recip * t.res_25_log) - (t.sh_c_coeff * cu(t.res_25_log));
}
// maximum adc value .. take into account the over sampling
// Maximum ADC value .. take into account the over sampling
constexpr raw_adc_t adc_max = MAX_RAW_THERMISTOR_VALUE;
const raw_adc_t adc_raw = constrain(raw, 1, adc_max - 1); // constrain to prevent divide-by-zero
@@ -3073,7 +3114,7 @@ void Temperature::disable_all_heaters() {
spiInit(MAX_TC_SPEED_BITS);
#endif
MAXTC_CS_WRITE(LOW); // enable MAXTC
MAXTC_CS_WRITE(LOW); // Enable MAXTC
DELAY_NS(100); // Ensure 100ns delay
// Read a big-endian temperature value without using a library
@@ -3082,7 +3123,7 @@ void Temperature::disable_all_heaters() {
if (i > 0) max_tc_temp <<= 8; // shift left if not the last byte
}
MAXTC_CS_WRITE(HIGH); // disable MAXTC
MAXTC_CS_WRITE(HIGH); // Disable MAXTC
#else
#if HAS_MAX6675_LIBRARY
MAX6675 &max6675ref = THERMO_SEL(max6675_0, max6675_1);
@@ -3293,7 +3334,7 @@ void Temperature::isr() {
static ADCSensorState adc_sensor_state = StartupDelay;
static uint8_t pwm_count = _BV(SOFT_PWM_SCALE);
// avoid multiple loads of pwm_count
// Avoid multiple loads of pwm_count
uint8_t pwm_count_tmp = pwm_count;
#if HAS_ADC_BUTTONS
@@ -3571,8 +3612,8 @@ void Temperature::isr() {
// 5: / 4 = 244.1406 Hz
pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE);
// increment slow_pwm_count only every 64th pwm_count,
// i.e. yielding a PWM frequency of 16/128 Hz (8s).
// Increment slow_pwm_count only every 64th pwm_count,
// i.e., yielding a PWM frequency of 16/128 Hz (8s).
if (((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0) {
slow_pwm_count++;
slow_pwm_count &= 0x7F;
@@ -3907,7 +3948,10 @@ void Temperature::isr() {
#if ENABLED(AUTO_REPORT_TEMPERATURES)
AutoReporter<Temperature::AutoReportTemp> Temperature::auto_reporter;
void Temperature::AutoReportTemp::report() { print_heater_states(active_extruder); SERIAL_EOL(); }
void Temperature::AutoReportTemp::report() {
print_heater_states(active_extruder OPTARG(HAS_TEMP_REDUNDANT, ENABLED(AUTO_REPORT_REDUNDANT)));
SERIAL_EOL();
}
#endif
#if HAS_HOTEND && HAS_STATUS_MESSAGE
@@ -4025,7 +4069,7 @@ void Temperature::isr() {
// Prevent a wait-forever situation if R is misused i.e. M109 R0
if (wants_to_cool) {
// break after MIN_COOLING_SLOPE_TIME seconds
// Break after MIN_COOLING_SLOPE_TIME seconds
// if the temperature did not drop at least MIN_COOLING_SLOPE_DEG
if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) {
if (old_temp - temp < float(MIN_COOLING_SLOPE_DEG)) break;
@@ -4047,7 +4091,7 @@ void Temperature::isr() {
wait_for_heatup = false;
#if HAS_DWIN_E3V2_BASIC
HMI_flag.heat_flag = 0;
duration_t elapsed = print_job_timer.duration(); // print timer
duration_t elapsed = print_job_timer.duration(); // Print timer
dwin_heat_time = elapsed.value;
#else
ui.reset_status();
+152 -77
View File
@@ -32,6 +32,7 @@
#include "../MarlinCore.h"
//#define DEBUG_TOOL_CHANGE
//#define DEBUG_TOOLCHANGE_FILAMENT_SWAP
#define DEBUG_OUT ENABLED(DEBUG_TOOL_CHANGE)
#include "../core/debug_out.h"
@@ -42,7 +43,6 @@
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
migration_settings_t migration = migration_defaults;
bool enable_first_prime;
#endif
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
@@ -150,6 +150,7 @@
#endif // SWITCHING_NOZZLE
// Move to position routines
void _line_to_current(const AxisEnum fr_axis, const float fscale=1) {
line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale);
}
@@ -899,10 +900,135 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
*/
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
#ifdef DEBUG_TOOLCHANGE_FILAMENT_SWAP
#define FS_DEBUG(V...) SERIAL_ECHOLNPGM("DEBUG: " V)
#else
#define FS_DEBUG(...) NOOP
#endif
// Define any variables required
static Flags<EXTRUDERS> extruder_was_primed; // Extruders primed status
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
bool enable_first_prime; // As set by M217 V
#endif
// Cool down with fan
inline void filament_swap_cooling() {
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed;
gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time));
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0;
#endif
}
/**
* Check if too cold to move the specified tool
*
* Returns TRUE if too cold to move (also echos message: STR_ERR_HOTEND_TOO_COLD)
* Returns FALSE if able to move.
*/
bool too_cold(uint8_t toolID){
if (TERN0(PREVENT_COLD_EXTRUSION, !DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(toolID))) {
SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD);
return true;
}
return false;
}
/**
* Cutting recovery -- Recover from cutting retraction that occurs at the end of nozzle priming
*
* If the active_extruder is up to temp (!too_cold):
* Extrude filament distance = toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT
* current_position.e = e;
* sync_plan_position_e();
*/
void extruder_cutting_recover(const_float_t e) {
if (!too_cold(active_extruder)) {
const float dist = toolchange_settings.extra_resume + (TOOLCHANGE_FS_WIPE_RETRACT);
FS_DEBUG("Performing Cutting Recover | Distance: ", dist, " | Speed: ", MMM_TO_MMS(toolchange_settings.unretract_speed), "mm/s");
unscaled_e_move(dist, MMM_TO_MMS(toolchange_settings.unretract_speed));
planner.synchronize();
FS_DEBUG("Set position to: ", e);
current_position.e = e;
sync_plan_position_e(); // Resume new E Position
}
}
/**
* Prime the currently selected extruder (Filament loading only)
*
* If too_cold(toolID) returns TRUE -> returns without moving extruder.
* Extruders filament = swap_length + extra prime, then performs cutting retraction if enabled.
* If cooling fan is enabled, calls filament_swap_cooling();
*/
void extruder_prime() {
if (too_cold(active_extruder)) {
FS_DEBUG("Priming Aborted - Nozzle Too Cold!");
return; // Extruder too cold to prime
}
float fr = toolchange_settings.unretract_speed; // Set default speed for unretract
#if ENABLED(TOOLCHANGE_FS_SLOW_FIRST_PRIME)
/*
* Perform first unretract movement at the slower Prime_Speed to avoid breakage on first prime
*/
static Flags<EXTRUDERS> extruder_did_first_prime; // Extruders first priming status
if (!extruder_did_first_prime[active_extruder]) {
extruder_did_first_prime.set(active_extruder); // Log first prime complete
// new nozzle - prime at user-specified speed.
FS_DEBUG("First time priming T", active_extruder, ", reducing speed from ", MMM_TO_MMS(fr), " to ", MMM_TO_MMS(toolchange_settings.prime_speed), "mm/s");
fr = toolchange_settings.prime_speed;
unscaled_e_move(0, MMM_TO_MMS(fr)); // Init planner with 0 length move
}
#endif
//Calculate and perform the priming distance
if (toolchange_settings.extra_prime >= 0) {
// Positive extra_prime value
// - Return filament at speed (fr) then extra_prime at prime speed
FS_DEBUG("Loading Filament for T", active_extruder, " | Distance: ", toolchange_settings.swap_length, " | Speed: ", MMM_TO_MMS(fr), "mm/s");
unscaled_e_move(toolchange_settings.swap_length, MMM_TO_MMS(fr)); // Prime (Unretract) filament by extruding equal to Swap Length (Unretract)
if (toolchange_settings.extra_prime > 0) {
FS_DEBUG("Performing Extra Priming for T", active_extruder, " | Distance: ", toolchange_settings.extra_prime, " | Speed: ", MMM_TO_MMS(toolchange_settings.prime_speed), "mm/s");
unscaled_e_move(toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); // Extra Prime Distance
}
}
else {
// Negative extra_prime value
// - Unretract distance (swap length) is reduced by the value of extra_prime
const float eswap = toolchange_settings.swap_length + toolchange_settings.extra_prime;
FS_DEBUG("Negative ExtraPrime value - Swap Return Length has been reduced from ", toolchange_settings.swap_length, " to ", eswap);
FS_DEBUG("Loading Filament for T", active_extruder, " | Distance: ", eswap, " | Speed: ", MMM_TO_MMS(fr), "mm/s");
unscaled_e_move(eswap, MMM_TO_MMS(fr));
}
extruder_was_primed.set(active_extruder); // Log that this extruder has been primed
// Cutting retraction
#if TOOLCHANGE_FS_WIPE_RETRACT
FS_DEBUG("Performing Cutting Retraction | Distance: ", -(TOOLCHANGE_FS_WIPE_RETRACT), " | Speed: ", MMM_TO_MMS(toolchange_settings.retract_speed), "mm/s");
unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed));
#endif
// Cool down with fan
filament_swap_cooling();
}
/**
* Sequence to Prime the currently selected extruder
* Raise Z, move the ToolChange_Park if enabled, prime the extruder, move back.
*/
void tool_change_prime() {
if (toolchange_settings.extra_prime > 0
&& TERN(PREVENT_COLD_EXTRUSION, !thermalManager.targetTooColdToExtrude(active_extruder), 1)
) {
FS_DEBUG(">>> tool_change_prime()");
if (!too_cold(active_extruder)) {
destination = current_position; // Remember the old position
const bool ok = TERN1(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park);
@@ -933,7 +1059,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
current_position.k = toolchange_settings.change_point.k,
current_position.u = toolchange_settings.change_point.u,
current_position.v = toolchange_settings.change_point.v,
current_position.w = toolchange_settings.change_point.w,
current_position.w = toolchange_settings.change_point.w
);
#endif
planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), active_extruder);
@@ -941,20 +1067,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
}
#endif
// Prime (All distances are added and slowed down to ensure secure priming in all circumstances)
unscaled_e_move(toolchange_settings.swap_length + toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed));
// Cutting retraction
#if TOOLCHANGE_FS_WIPE_RETRACT
unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed));
#endif
// Cool down with fan
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed;
gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time));
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0;
#endif
extruder_prime();
// Move back
#if ENABLED(TOOLCHANGE_PARK)
@@ -968,13 +1081,11 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
}
#endif
// Cutting recover
unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed));
// Resume at the old E position
current_position.e = destination.e;
sync_plan_position_e();
extruder_cutting_recover(destination.e); // Cutting recover
}
FS_DEBUG("<<< tool_change_prime");
}
#endif // TOOLCHANGE_FILAMENT_SWAP
@@ -1051,12 +1162,10 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
TEMPORARY_BED_LEVELING_STATE(false);
#endif
// First tool priming. To prime again, reboot the machine.
// First tool priming. To prime again, reboot the machine. -- Should only occur for first T0 after powerup!
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
static bool first_tool_is_primed = false;
if (new_tool == old_tool && !first_tool_is_primed && enable_first_prime) {
if (enable_first_prime && old_tool == 0 && new_tool == 0 && !extruder_was_primed[0]) {
tool_change_prime();
first_tool_is_primed = true;
TERN_(TOOLCHANGE_FS_INIT_BEFORE_SWAP, toolchange_extruder_ready.set(old_tool)); // Primed and initialized
}
#endif
@@ -1082,20 +1191,17 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
// Unload / Retract
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
const bool should_swap = can_move_away && toolchange_settings.swap_length,
too_cold = TERN0(PREVENT_COLD_EXTRUSION,
!DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(old_tool) || thermalManager.targetTooColdToExtrude(new_tool))
);
const bool should_swap = can_move_away && toolchange_settings.swap_length;
if (should_swap) {
if (too_cold) {
SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD);
if (too_cold(old_tool)) {
// If SingleNozzle setup is too cold, unable to perform tool_change.
if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; }
}
else {
// For first new tool, change without unloading the old. 'Just prime/init the new'
if (TERN1(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_primed))
unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed));
TERN_(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_primed = true); // The first new tool will be primed by toolchanging
else if (extruder_was_primed[old_tool]) {
// Retract the old extruder if it was previously primed
// To-Do: Should SingleNozzle always retract?
FS_DEBUG("Retracting Filament for T", old_tool, ". | Distance: ", toolchange_settings.swap_length, " | Speed: ", MMM_TO_MMS(toolchange_settings.retract_speed), "mm/s");
unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed));
}
}
#endif
@@ -1138,7 +1244,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
current_position.k = toolchange_settings.change_point.k,
current_position.u = toolchange_settings.change_point.u,
current_position.v = toolchange_settings.change_point.v,
current_position.w = toolchange_settings.change_point.w,
current_position.w = toolchange_settings.change_point.w
);
#endif
planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), old_tool);
@@ -1210,36 +1316,8 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
#endif
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
if (should_swap && !too_cold) {
float fr = toolchange_settings.unretract_speed;
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
if (!toolchange_extruder_ready[new_tool]) {
toolchange_extruder_ready.set(new_tool);
fr = toolchange_settings.prime_speed; // Next move is a prime
unscaled_e_move(0, MMM_TO_MMS(fr)); // Init planner with 0 length move
}
#endif
// Unretract (or Prime)
unscaled_e_move(toolchange_settings.swap_length, MMM_TO_MMS(fr));
// Extra Prime
unscaled_e_move(toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed));
// Cutting retraction
#if TOOLCHANGE_FS_WIPE_RETRACT
unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed));
#endif
// Cool down with fan
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed;
gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time));
thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0;
#endif
}
if (should_swap && !too_cold(active_extruder))
extruder_prime(); // Prime selected Extruder
#endif
// Prevent a move outside physical bounds
@@ -1280,11 +1358,8 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
else DEBUG_ECHOLNPGM("Move back skipped");
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
if (should_swap && !too_cold) {
// Cutting recover
unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed));
current_position.e = 0;
sync_plan_position_e(); // New extruder primed and set to 0
if (should_swap && !too_cold(active_extruder)) {
extruder_cutting_recover(0); // New extruder primed and set to 0
// Restart Fan
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
@@ -1342,7 +1417,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
#endif
}
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, active_extruder);
SERIAL_ECHOLNPGM(STR_ACTIVE_EXTRUDER, active_extruder);
#endif // HAS_MULTI_EXTRUDER
}
+15 -9
View File
@@ -29,24 +29,30 @@
typedef struct {
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
float swap_length, extra_prime, extra_resume;
int16_t prime_speed, retract_speed, unretract_speed, fan, fan_speed, fan_time;
float swap_length; // M217 S
float extra_prime; // M217 E
float extra_resume; // M217 B
int16_t prime_speed; // M217 P
int16_t retract_speed; // M217 R
int16_t unretract_speed; // M217 U
uint8_t fan_speed; // M217 F
uint8_t fan_time; // M217 D
#endif
#if ENABLED(TOOLCHANGE_PARK)
bool enable_park;
xyz_pos_t change_point;
bool enable_park; // M217 W
xyz_pos_t change_point; // M217 X Y I J K C H O
#endif
float z_raise;
float z_raise; // M217 Z
} toolchange_settings_t;
extern toolchange_settings_t toolchange_settings;
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
void tool_change_prime();
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
extern bool enable_first_prime; // M217 V
#endif
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
extern bool enable_first_prime;
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
void tool_change_prime(); // Prime the currently selected extruder
#endif
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
+1 -1
View File
@@ -127,7 +127,7 @@
#define LCD_RESET_PIN 16
#define LCD_CONTRAST_DEFAULT 220
#define LCD_CONTRAST_INIT 220
#define LCD_BACKLIGHT_PIN -1
#else
+1 -1
View File
@@ -107,7 +107,7 @@
#define LCD_CONTRAST_MIN 0
#define LCD_CONTRAST_MAX 100
#define LCD_CONTRAST_DEFAULT 30
#define LCD_CONTRAST_INIT 30
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
#if IS_NEWPANEL
@@ -157,7 +157,7 @@
#define NEOPIXEL_PIN PB9
#endif
#define LCD_CONTRAST_DEFAULT 255
#define LCD_CONTRAST_INIT 255
#else
#define LCD_PINS_RS PC15
#define LCD_PINS_ENABLE PB6
@@ -61,10 +61,8 @@
#define USB_NO_TEST_UNIT_READY // Required for removable media adapter
#define USB_HOST_MANUAL_POLL // Optimization to shut off IRQ automatically
// Workarounds for keeping Marlin's watchdog timer from barking...
void marlin_yield() {
thermalManager.manage_heater();
}
// Workarounds to keep Marlin's watchdog timer from barking...
void marlin_yield() { thermalManager.manage_heater(); }
#define SYSTEM_OR_SPECIAL_YIELD(...) marlin_yield();
#define delay(x) safe_delay(x)
@@ -82,6 +80,7 @@
#define UHS_START (usb.Init() == 0)
#define UHS_STATE(state) UHS_USB_HOST_STATE_##state
#elif ENABLED(USE_OTG_USB_HOST)
#if HAS_SD_HOST_DRIVE
@@ -93,7 +92,9 @@
#define UHS_START usb.start()
#define rREVISION 0
#define UHS_STATE(state) USB_STATE_##state
#else
#include "lib-uhs2/Usb.h"
#include "lib-uhs2/masstorage.h"
@@ -102,6 +103,7 @@
#define UHS_START usb.start()
#define UHS_STATE(state) USB_STATE_##state
#endif
#include "Sd2Card_FlashDrive.h"
@@ -271,11 +273,11 @@ bool DiskIODriver_USBFlash::init(const uint8_t, const pin_t) {
if (!isInserted()) return false;
#if USB_DEBUG >= 1
const uint32_t sectorSize = bulk.GetSectorSize(0);
if (sectorSize != 512) {
SERIAL_ECHOLNPGM("Expecting sector size of 512. Got: ", sectorSize);
return false;
}
const uint32_t sectorSize = bulk.GetSectorSize(0);
if (sectorSize != 512) {
SERIAL_ECHOLNPGM("Expecting sector size of 512. Got: ", sectorSize);
return false;
}
#endif
#if USB_DEBUG >= 3
@@ -27,19 +27,18 @@
#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && DISABLED(USE_UHS3_USB)
#if !PINS_EXIST(USB_CS, USB_INTR)
#error "USB_FLASH_DRIVE_SUPPORT requires USB_CS_PIN and USB_INTR_PIN to be defined."
#endif
#include "Usb.h"
#include "usbhost.h"
uint8_t MAX3421e::vbusState = 0;
// constructor
void MAX3421e::cs() {
WRITE(USB_CS_PIN,0);
}
void MAX3421e::ncs() {
WRITE(USB_CS_PIN,1);
}
void MAX3421e::cs() { WRITE(USB_CS_PIN, LOW); }
void MAX3421e::ncs() { WRITE(USB_CS_PIN, HIGH); }
// write single byte into MAX3421 register
void MAX3421e::regWr(uint8_t reg, uint8_t data) {
@@ -76,8 +75,8 @@ uint8_t MAX3421e::regRd(uint8_t reg) {
ncs();
return rv;
}
// multiple-byte register read
// multiple-byte register read
// return a pointer to a memory position after last read
uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
cs();
@@ -86,8 +85,8 @@ uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
ncs();
return data_p;
}
// GPIO read. See gpioWr for explanation
// GPIO read. See gpioWr for explanation
// GPIN pins are in high nybbles of IOPINS1, IOPINS2
uint8_t MAX3421e::gpioRd() {
return (regRd(rIOPINS2) & 0xF0) | // pins 4-7, clean lower nybble
@@ -29,7 +29,7 @@ if pioutil.is_pio_build():
# It useful to keep two live versions: a debug version for debugging and another for
# release, for flashing when upload is not done automatically by jlink/stlink.
# Without this, PIO needs to recompile everything twice for any small change.
if env.GetBuildType() == "debug" and env.get('UPLOAD_PROTOCOL') not in ['jlink', 'stlink']:
if env.GetBuildType() == "debug" and env.get('UPLOAD_PROTOCOL') not in ['jlink', 'stlink', 'custom']:
env['BUILD_DIR'] = '$PROJECT_BUILD_DIR/$PIOENV/debug'
# On some platform, F_CPU is a runtime variable. Since it's used to convert from ns
@@ -57,6 +57,6 @@ if pioutil.is_pio_build():
def rename_target(source, target, env):
firmware = os.path.join(target[0].dir.path, board.get("build.rename"))
os.rename(target[0].path, firmware)
os.replace(target[0].path, firmware)
marlin.add_post_action(rename_target)
@@ -102,6 +102,10 @@ if pioutil.is_pio_build():
for f in [ "ultralcd_DOGM.cpp", "ultralcd_DOGM.h" ]:
if os.path.isfile(os.path.join(p, f)):
mixedin += [ f ]
p = os.path.join(env['PROJECT_DIR'], "Marlin", "src", "feature", "bedlevel", "abl")
for f in [ "abl.cpp", "abl.h" ]:
if os.path.isfile(os.path.join(p, f)):
mixedin += [ f ]
if mixedin:
err = "ERROR: Old files fell into your Marlin folder. Remove %s and try again" % ", ".join(mixedin)
raise SystemExit(err)
+9 -1
View File
@@ -74,6 +74,8 @@ if [[ $ACTION == "init" ]]; then
# a 'BASE' branch with only defaults as a starting point.
#
SED=$(which gsed sed | head -n1)
echo "- Initializing BASE branch..."
# Use the import branch as the source
@@ -82,6 +84,13 @@ if [[ $ACTION == "init" ]]; then
# Copy to a temporary location
TEMP=$( mktemp -d ) ; cp -R config $TEMP
# Strip all #error lines
IFS=$'\n'; set -f
for fn in $( find $TEMP/config -type f -name "Configuration.h" ); do
$SED -i "20,30{/#error/d}" $fn
done
unset IFS; set +f
# Make sure we're not on the 'BASE' branch...
git checkout init-repo >/dev/null 2>&1 || exit
@@ -149,7 +158,6 @@ if [[ $ACTION == "init" ]]; then
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset TPARA..." >/dev/null
# Update the %VERSION% in the README.md file
SED=$(which gsed sed | head -n1)
VERS=$( echo $EXPORT | $SED 's/release-//' )
eval "${SED} -E -i~ -e 's/%VERSION%/$VERS/g' README.md"
rm -f README.md~
+10 -4
View File
@@ -26,7 +26,7 @@ opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \
EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 \
NUM_Z_STEPPER_DRIVERS 4 \
DEFAULT_Kp_LIST '{ 22.2, 20.0, 21.0, 19.0, 18.0 }' DEFAULT_Ki_LIST '{ 1.08 }' DEFAULT_Kd_LIST '{ 114.0, 112.0, 110.0, 108.0 }'
opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_INIT_BEFORE_SWAP TOOLCHANGE_FS_PRIME_FIRST_USED \
opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_SLOW_FIRST_PRIME TOOLCHANGE_FS_PRIME_FIRST_USED \
PID_PARAMS_PER_HOTEND Z_MULTI_ENDSTOPS
exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Quad Z + Endstops" "$3"
@@ -34,9 +34,15 @@ restore_configs
opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \
EXTRUDERS 3 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 \
SERVO_DELAY '{ 300, 300, 300 }' \
SWITCHING_TOOLHEAD_X_POS '{ 215, 0 ,0 }'
opt_enable SWITCHING_TOOLHEAD TOOL_SENSOR
exec_test $1 $2 "BigTreeTech GTR | Switching Toolhead | Tool Sensors" "$3"
SWITCHING_TOOLHEAD_X_POS '{ 215, 0 ,0 }' \
MPC_HEATER_POWER '{ 40.0f, 40.0f, 40.0f }' \
MPC_BLOCK_HEAT_CAPACITY '{ 16.7f, 16.7f, 16.7f }' \
MPC_SENSOR_RESPONSIVENESS '{ 0.22f, 0.22f, 0.22f }' \
MPC_AMBIENT_XFER_COEFF '{ 0.068f, 0.068f, 0.068f }' \
MPC_AMBIENT_XFER_COEFF_FAN255 '{ 0.097f, 0.097f, 0.097f }'
opt_enable SWITCHING_TOOLHEAD TOOL_SENSOR MPCTEMP
opt_disable PIDTEMP
exec_test $1 $2 "BigTreeTech GTR | MPC | Switching Toolhead | Tool Sensors" "$3"
# clean up
restore_configs
+1 -1
View File
@@ -15,7 +15,7 @@ set -e
restore_configs
opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB SERIAL_PORT_3 3 \
NEOPIXEL_TYPE NEO_RGB RGB_LED_R_PIN P2_12 RGB_LED_G_PIN P1_23 RGB_LED_B_PIN P1_22 RGB_LED_W_PIN P1_24
NEOPIXEL_TYPE NEO_GRB RGB_LED_R_PIN P2_12 RGB_LED_G_PIN P1_23 RGB_LED_B_PIN P1_22 RGB_LED_W_PIN P1_24
opt_enable FYSETC_MINI_12864_2_1 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 RGBW_LED E_DUAL_STEPPER_DRIVERS \
NEOPIXEL_LED NEOPIXEL_IS_SEQUENTIAL NEOPIXEL_STARTUP_TEST NEOPIXEL_BKGD_INDEX_FIRST NEOPIXEL_BKGD_INDEX_LAST NEOPIXEL_BKGD_COLOR NEOPIXEL_BKGD_ALWAYS_ON
exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel" "$3"
-1
View File
@@ -13,7 +13,6 @@ restore_configs
opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 SERIAL_PORT 1 SERIAL_PORT_2 -1 \
X_DRIVER_TYPE TMC2209 Y_DRIVER_TYPE TMC2209 Z_DRIVER_TYPE TMC2209 E0_DRIVER_TYPE TMC2209
opt_enable PINS_DEBUGGING Z_IDLE_HEIGHT
exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - Basic Config with TMC2209 HW Serial" "$3"
# clean up
-1
View File
@@ -13,7 +13,6 @@ restore_configs
opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 SERIAL_PORT 1 SERIAL_PORT_2 -1 \
X_DRIVER_TYPE TMC2209 Y_DRIVER_TYPE TMC2209 Z_DRIVER_TYPE TMC2209 E0_DRIVER_TYPE TMC2209
opt_enable PINS_DEBUGGING Z_IDLE_HEIGHT
exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - Basic Config with TMC2209 HW Serial" "$3"
# clean up
+2 -3
View File
@@ -181,7 +181,6 @@ opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_C
AXIS_RELATIVE_MODES '{ false, false, false }'
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
LASER_FEATURE AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_COOLANT_FLOW_METER MEATPACK_ON_SERIAL_PORT_1
exec_test $1 $2 "MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air Assist | Cooler | Flowmeter | 12864 LCD | meatpack | SERIAL_PORT_2 " "$3"
#
@@ -196,7 +195,6 @@ opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_C
AXIS_RELATIVE_MODES '{ false, false, false }'
opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
LASER_FEATURE AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_COOLANT_FLOW_METER I2C_AMMETER
exec_test $1 $2 "MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air Assist | Cooler | Flowmeter | 44780 LCD " "$3"
#
@@ -207,7 +205,8 @@ opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 1 \
TEMP_SENSOR_0 -2 TEMP_SENSOR_REDUNDANT -2 \
TEMP_SENSOR_REDUNDANT_SOURCE E1 TEMP_SENSOR_REDUNDANT_TARGET E0 \
TEMP_0_CS_PIN 11 TEMP_1_CS_PIN 12
opt_enable MPCTEMP
opt_disable PIDTEMP
exec_test $1 $2 "MEGA2560 RAMPS | Redundant temperature sensor | 2x MAX6675" "$3"
#