From 70fa4c9323543dfb65d10969838899575406cae6 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 1 Jul 2020 16:18:20 -0500 Subject: [PATCH] Per-Hotend Default PIDs (#18483) --- Marlin/src/gcode/config/M301.cpp | 3 ++ Marlin/src/inc/Conditionals_LCD.h | 2 + Marlin/src/inc/SanityCheck.h | 46 ++++++++++-------- Marlin/src/lcd/menu/menu_advanced.cpp | 12 ++--- Marlin/src/module/configuration_store.cpp | 59 ++++++++++++++++++++--- Marlin/src/module/temperature.h | 35 ++++---------- 6 files changed, 96 insertions(+), 61 deletions(-) diff --git a/Marlin/src/gcode/config/M301.cpp b/Marlin/src/gcode/config/M301.cpp index 54d32c865..a68b64e05 100644 --- a/Marlin/src/gcode/config/M301.cpp +++ b/Marlin/src/gcode/config/M301.cpp @@ -30,6 +30,8 @@ /** * M301: Set PID parameters P I D (and optionally C, L) * + * E[extruder] Default: 0 + * * P[float] Kp term * I[float] Ki term (unscaled) * D[float] Kd term (unscaled) @@ -65,6 +67,7 @@ void GcodeSuite::M301() { #endif thermalManager.updatePID(); + SERIAL_ECHO_START(); #if ENABLED(PID_PARAMS_PER_HOTEND) SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 71b5d7a89..639c5765a 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -477,6 +477,8 @@ #define HAS_MULTI_HOTEND 1 #define HAS_HOTEND_OFFSET 1 #endif +#else + #undef PID_PARAMS_PER_HOTEND #endif // Helper macros for extruder and hotend arrays diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index d99330916..87caa23a8 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1629,28 +1629,8 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal #endif /** - * Test Heater, Temp Sensor, and Extruder Pins; Sensor Type must also be set. + * A Sensor ID has to be set for each heater */ -#if !HAS_HEATER_0 - #error "HEATER_0_PIN not defined for this board." -#elif !ANY_PIN(TEMP_0, MAX6675_SS) - #error "TEMP_0_PIN not defined for this board." -#elif ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) - #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." -#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) - #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." -#elif EXTRUDERS && TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required with any extruders." -#endif - -// Pins are required for heaters -#if ENABLED(HEATER_0_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS) - #error "MAX6675_SS_PIN (required for TEMP_SENSOR_0) not defined for this board." -#elif HAS_HOTEND && !HAS_TEMP_HOTEND - #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." -#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 - #error "HEATER_1_PIN not defined for this board." -#endif #if HAS_MULTI_HOTEND #if ENABLED(HEATER_1_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS2) @@ -1792,6 +1772,30 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal #error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT." #endif +/** + * Test Heater, Temp Sensor, and Extruder Pins + */ +#if !HAS_HEATER_0 + #error "HEATER_0_PIN not defined for this board." +#elif !ANY_PIN(TEMP_0, MAX6675_SS) + #error "TEMP_0_PIN not defined for this board." +#elif ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR)) + #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." +#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) + #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." +#elif EXTRUDERS && TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required if there are any extruders." +#endif + +// Pins are required for heaters +#if ENABLED(HEATER_0_USES_MAX6675) && !PIN_EXISTS(MAX6675_SS) + #error "MAX6675_SS_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif HAS_HOTEND && !HAS_TEMP_HOTEND + #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 + #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." +#endif + /** * Temperature status LEDs */ diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index b57e442b6..d53a4d249 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -205,16 +205,12 @@ void menu_cancelobject(); // 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(int16_t e) { - #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 - UNUSED(e); - #endif + TERN(PID_PARAMS_PER_HOTEND,,UNUSED(e)); PID_PARAM(Ki, e) = scalePID_i(raw_Ki); thermalManager.updatePID(); } void copy_and_scalePID_d(int16_t e) { - #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 - UNUSED(e); - #endif + TERN(PID_PARAMS_PER_HOTEND,,UNUSED(e)); PID_PARAM(Kd, e) = scalePID_d(raw_Kd); thermalManager.updatePID(); } @@ -239,7 +235,7 @@ void menu_cancelobject(); #if HAS_HOTEND DEFINE_PIDTEMP_FUNCS(0); - #if BOTH(HAS_MULTI_HOTEND, PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) REPEAT_S(1, HOTENDS, DEFINE_PIDTEMP_FUNCS) #endif #endif @@ -314,7 +310,7 @@ void menu_cancelobject(); #endif PID_EDIT_MENU_ITEMS(0); - #if BOTH(HAS_MULTI_HOTEND, PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) REPEAT_S(1, HOTENDS, PID_EDIT_MENU_ITEMS) #endif diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 41ce618a0..8ff873111 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -2587,12 +2587,59 @@ void MarlinSettings::reset() { // #if ENABLED(PIDTEMP) + #if ENABLED(PID_PARAMS_PER_HOTEND) + constexpr float defKp[] = + #ifdef DEFAULT_Kp_LIST + DEFAULT_Kp_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kp) + #endif + , defKi[] = + #ifdef DEFAULT_Ki_LIST + DEFAULT_Ki_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Ki) + #endif + , defKd[] = + #ifdef DEFAULT_Kd_LIST + DEFAULT_Kd_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kd) + #endif + ; + static_assert(WITHIN(COUNT(defKp), 1, HOTENDS), "DEFAULT_Kp_LIST must have between 1 and HOTENDS items."); + static_assert(WITHIN(COUNT(defKi), 1, HOTENDS), "DEFAULT_Ki_LIST must have between 1 and HOTENDS items."); + static_assert(WITHIN(COUNT(defKd), 1, HOTENDS), "DEFAULT_Kd_LIST must have between 1 and HOTENDS items."); + #if ENABLED(PID_EXTRUSION_SCALING) + constexpr float defKc[] = + #ifdef DEFAULT_Kc_LIST + DEFAULT_Kc_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kc) + #endif + ; + static_assert(WITHIN(COUNT(defKc), 1, HOTENDS), "DEFAULT_Kc_LIST must have between 1 and HOTENDS items."); + #endif + #if ENABLED(PID_FAN_SCALING) + constexpr float defKf[] = + #ifdef DEFAULT_Kf_LIST + DEFAULT_Kf_LIST + #else + ARRAY_BY_HOTENDS1(DEFAULT_Kf) + #endif + ; + static_assert(WITHIN(COUNT(defKf), 1, HOTENDS), "DEFAULT_Kf_LIST must have between 1 and HOTENDS items."); + #endif + #define PID_DEFAULT(N,E) def##N[E] + #else + #define PID_DEFAULT(N,E) DEFAULT_##N + #endif HOTEND_LOOP() { - PID_PARAM(Kp, e) = float(DEFAULT_Kp); - PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki); - PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd); - TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = DEFAULT_Kc); - TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = DEFAULT_Kf); + PID_PARAM(Kp, e) = float(PID_DEFAULT(Kp, ALIM(e, defKp))); + PID_PARAM(Ki, e) = scalePID_i(PID_DEFAULT(Ki, ALIM(e, defKi))); + PID_PARAM(Kd, e) = scalePID_d(PID_DEFAULT(Kd, ALIM(e, defKd))); + TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = float(PID_DEFAULT(Kc, ALIM(e, defKc)))); + TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = float(PID_DEFAULT(Kf, ALIM(e, defKf)))); } #endif @@ -3140,7 +3187,7 @@ void MarlinSettings::reset() { HOTEND_LOOP() { CONFIG_ECHO_START(); SERIAL_ECHOPAIR_P( - #if BOTH(HAS_MULTI_HOTEND, PID_PARAMS_PER_HOTEND) + #if ENABLED(PID_PARAMS_PER_HOTEND) PSTR(" M301 E"), e, SP_P_STR #else diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index a6d702646..d0d7858c7 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -37,13 +37,8 @@ #define SOFT_PWM_SCALE 0 #endif -#if HOTENDS <= 1 - #define HOTEND_INDEX 0 - #define E_NAME -#else - #define HOTEND_INDEX e - #define E_NAME e -#endif +#define HOTEND_INDEX TERN(HAS_MULTI_HOTEND, e, 0) +#define E_NAME TERN_(HAS_MULTI_HOTEND, e) // Identifiers for other heaters typedef enum : int8_t { @@ -74,30 +69,18 @@ hotend_pid_t; typedef IF<(LPQ_MAX_LEN > 255), uint16_t, uint8_t>::type lpq_ptr_t; #endif +#define PID_PARAM(F,H) _PID_##F(TERN(PID_PARAMS_PER_HOTEND, H, 0)) +#define _PID_Kp(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kp, NAN) +#define _PID_Ki(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Ki, NAN) +#define _PID_Kd(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kd, NAN) #if ENABLED(PIDTEMP) - #define _PID_Kp(H) Temperature::temp_hotend[H].pid.Kp - #define _PID_Ki(H) Temperature::temp_hotend[H].pid.Ki - #define _PID_Kd(H) Temperature::temp_hotend[H].pid.Kd - #if ENABLED(PID_EXTRUSION_SCALING) - #define _PID_Kc(H) Temperature::temp_hotend[H].pid.Kc - #else - #define _PID_Kc(H) 1 - #endif - - #if ENABLED(PID_FAN_SCALING) - #define _PID_Kf(H) Temperature::temp_hotend[H].pid.Kf - #else - #define _PID_Kf(H) 0 - #endif + #define _PID_Kc(H) TERN(PID_EXTRUSION_SCALING, Temperature::temp_hotend[H].pid.Kc, 1) + #define _PID_Kf(H) TERN(PID_FAN_SCALING, Temperature::temp_hotend[H].pid.Kf, 0) #else - #define _PID_Kp(H) NAN - #define _PID_Ki(H) NAN - #define _PID_Kd(H) NAN #define _PID_Kc(H) 1 + #define _PID_Kf(H) 0 #endif -#define PID_PARAM(F,H) _PID_##F(H) - /** * States for ADC reading in the ISR */