From b72238f4063fcf67f3155fdf732d50f4860d795c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 9 Jul 2016 19:47:11 -0700 Subject: [PATCH 1/3] Invariant get_pid_output with HOTENDS < 2 --- Marlin/temperature.cpp | 84 +++++++++++++++++++++--------------------- Marlin/temperature.h | 27 +++++++++----- 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index fb9b40cf0f..2fa6074b2c 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -514,88 +514,86 @@ void Temperature::min_temp_error(uint8_t e) { } float Temperature::get_pid_output(int e) { + #if HOTENDS == 1 + UNUSED(e); + #define _HOTEND_TEST true + #define _HOTEND_EXTRUDER active_extruder + #else + #define _HOTEND_TEST e == active_extruder + #define _HOTEND_EXTRUDER e + #endif float pid_output; #if ENABLED(PIDTEMP) #if DISABLED(PID_OPENLOOP) - pid_error[e] = target_temperature[e] - current_temperature[e]; - dTerm[e] = K2 * PID_PARAM(Kd, e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e]; - temp_dState[e] = current_temperature[e]; - if (pid_error[e] > PID_FUNCTIONAL_RANGE) { + pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; + dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX]; + temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; + if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) { pid_output = BANG_MAX; - pid_reset[e] = true; + pid_reset[HOTEND_INDEX] = true; } - else if (pid_error[e] < -(PID_FUNCTIONAL_RANGE) || target_temperature[e] == 0) { + else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0) { pid_output = 0; - pid_reset[e] = true; + pid_reset[HOTEND_INDEX] = true; } else { - if (pid_reset[e]) { - temp_iState[e] = 0.0; - pid_reset[e] = false; + if (pid_reset[HOTEND_INDEX]) { + temp_iState[HOTEND_INDEX] = 0.0; + pid_reset[HOTEND_INDEX] = false; } - pTerm[e] = PID_PARAM(Kp, e) * pid_error[e]; - temp_iState[e] += pid_error[e]; - temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); - iTerm[e] = PID_PARAM(Ki, e) * temp_iState[e]; + pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX]; + temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX]; + temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX], temp_iState_min[HOTEND_INDEX], temp_iState_max[HOTEND_INDEX]); + iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX]; - pid_output = pTerm[e] + iTerm[e] - dTerm[e]; - - #if ENABLED(SINGLENOZZLE) - #define _NOZZLE_TEST true - #define _NOZZLE_EXTRUDER active_extruder - #define _CTERM_INDEX 0 - #else - #define _NOZZLE_TEST e == active_extruder - #define _NOZZLE_EXTRUDER e - #define _CTERM_INDEX e - #endif + pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX]; #if ENABLED(PID_ADD_EXTRUSION_RATE) - cTerm[_CTERM_INDEX] = 0; - if (_NOZZLE_TEST) { + cTerm[HOTEND_INDEX] = 0; + if (_HOTEND_TEST) { long e_position = stepper.position(E_AXIS); - if (e_position > last_position[_NOZZLE_EXTRUDER]) { - lpq[lpq_ptr++] = e_position - last_position[_NOZZLE_EXTRUDER]; - last_position[_NOZZLE_EXTRUDER] = e_position; + if (e_position > last_position[_HOTEND_EXTRUDER]) { + lpq[lpq_ptr++] = e_position - last_position[_HOTEND_EXTRUDER]; + last_position[_HOTEND_EXTRUDER] = e_position; } else { lpq[lpq_ptr++] = 0; } if (lpq_ptr >= lpq_len) lpq_ptr = 0; - cTerm[_CTERM_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, e); - pid_output += cTerm[e]; + cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX); + pid_output += cTerm[HOTEND_INDEX]; } #endif //PID_ADD_EXTRUSION_RATE if (pid_output > PID_MAX) { - if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration + if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration pid_output = PID_MAX; } else if (pid_output < 0) { - if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration + if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration pid_output = 0; } } #else - pid_output = constrain(target_temperature[e], 0, PID_MAX); + pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX); #endif //PID_OPENLOOP #if ENABLED(PID_DEBUG) SERIAL_ECHO_START; - SERIAL_ECHOPAIR(MSG_PID_DEBUG, e); - SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); - SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[e]); - SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[e]); - SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]); #if ENABLED(PID_ADD_EXTRUSION_RATE) - SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]); #endif SERIAL_EOL; #endif //PID_DEBUG #else /* PID off */ - pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0; + pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0; #endif return pid_output; @@ -672,7 +670,7 @@ void Temperature::manage_heater() { #endif // Loop through all hotends - for (int e = 0; e < HOTENDS; e++) { + for (uint8_t e = 0; e < HOTENDS; e++) { #if ENABLED(THERMAL_PROTECTION_HOTENDS) thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 60aa80d6a7..f8b190800b 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -38,6 +38,16 @@ #define SOFT_PWM_SCALE 0 #endif +#if HOTENDS == 1 + #define HOTEND_ARG 0 + #define HOTEND_INDEX 0 + #define EXTRUDER_ARG 0 +#else + #define HOTEND_ARG hotend + #define HOTEND_INDEX e + #define EXTRUDER_ARG active_extruder +#endif + class Temperature { public: @@ -112,7 +122,12 @@ class Temperature { #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) static float extrude_min_temp; - static bool tooColdToExtrude(uint8_t e) { return degHotend(e) < extrude_min_temp; } + static bool tooColdToExtrude(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return degHotend(HOTEND_INDEX) < extrude_min_temp; + } #else static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } #endif @@ -230,12 +245,6 @@ class Temperature { //inline so that there is no performance decrease. //deg=degreeCelsius - #if HOTENDS == 1 - #define HOTEND_ARG 0 - #else - #define HOTEND_ARG hotend - #endif - static float degHotend(uint8_t hotend) { #if HOTENDS == 1 UNUSED(hotend); @@ -329,8 +338,8 @@ class Temperature { #if ENABLED(AUTOTEMP) if (planner.autotemp_enabled) { planner.autotemp_enabled = false; - if (degTargetHotend(active_extruder) > planner.autotemp_min) - setTargetHotend(0, active_extruder); + if (degTargetHotend(EXTRUDER_ARG) > planner.autotemp_min) + setTargetHotend(0, EXTRUDER_ARG); } #endif } From 3e1bbd5e2752760f2907e3a6833676851cfb6aa0 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 9 Jul 2016 20:11:23 -0700 Subject: [PATCH 2/3] Indentation in gcode_M100 --- Marlin/M100_Free_Mem_Chk.cpp | 125 +++++++++++++++++------------------ 1 file changed, 61 insertions(+), 64 deletions(-) diff --git a/Marlin/M100_Free_Mem_Chk.cpp b/Marlin/M100_Free_Mem_Chk.cpp index c3027794c5..8804bab6a7 100644 --- a/Marlin/M100_Free_Mem_Chk.cpp +++ b/Marlin/M100_Free_Mem_Chk.cpp @@ -57,9 +57,6 @@ void prt_hex_byte(unsigned int); void prt_hex_word(unsigned int); int how_many_E5s_are_here(unsigned char*); - - - void gcode_M100() { static int m100_not_initialized = 1; unsigned char* sp, *ptr; @@ -73,49 +70,49 @@ void gcode_M100() { // probably caused by bad pointers. Any unexpected values will be flagged in // the right hand column to help spotting them. // -#if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command - if (code_seen('D')) { - ptr = (unsigned char*) __brkval; - // - // We want to start and end the dump on a nice 16 byte boundry even though - // the values we are using are not 16 byte aligned. - // - SERIAL_ECHOPGM("\n__brkval : "); - prt_hex_word((unsigned int) ptr); - ptr = (unsigned char*)((unsigned long) ptr & 0xfff0); - sp = top_of_stack(); - SERIAL_ECHOPGM("\nStack Pointer : "); - prt_hex_word((unsigned int) sp); - SERIAL_EOL; - sp = (unsigned char*)((unsigned long) sp | 0x000f); - n = sp - ptr; - // - // This is the main loop of the Dump command. - // - while (ptr < sp) { - prt_hex_word((unsigned int) ptr); // Print the address - SERIAL_CHAR(':'); - for (i = 0; i < 16; i++) { // and 16 data bytes - prt_hex_byte(*(ptr + i)); - SERIAL_CHAR(' '); - delay(2); - } - SERIAL_CHAR('|'); // now show where non 0xE5's are - for (i = 0; i < 16; i++) { - delay(2); - if (*(ptr + i) == 0xe5) + #if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command + if (code_seen('D')) { + ptr = (unsigned char*) __brkval; + // + // We want to start and end the dump on a nice 16 byte boundry even though + // the values we are using are not 16 byte aligned. + // + SERIAL_ECHOPGM("\n__brkval : "); + prt_hex_word((unsigned int) ptr); + ptr = (unsigned char*)((unsigned long) ptr & 0xfff0); + sp = top_of_stack(); + SERIAL_ECHOPGM("\nStack Pointer : "); + prt_hex_word((unsigned int) sp); + SERIAL_EOL; + sp = (unsigned char*)((unsigned long) sp | 0x000f); + n = sp - ptr; + // + // This is the main loop of the Dump command. + // + while (ptr < sp) { + prt_hex_word((unsigned int) ptr); // Print the address + SERIAL_CHAR(':'); + for (i = 0; i < 16; i++) { // and 16 data bytes + prt_hex_byte(*(ptr + i)); SERIAL_CHAR(' '); - else - SERIAL_CHAR('?'); + delay(2); + } + SERIAL_CHAR('|'); // now show where non 0xE5's are + for (i = 0; i < 16; i++) { + delay(2); + if (*(ptr + i) == 0xe5) + SERIAL_CHAR(' '); + else + SERIAL_CHAR('?'); + } + SERIAL_EOL; + ptr += 16; + delay(2); } - SERIAL_EOL; - ptr += 16; - delay(2); + SERIAL_ECHOLNPGM("Done."); + return; } - SERIAL_ECHOLNPGM("Done."); - return; - } -#endif + #endif // // M100 F requests the code to return the number of free bytes in the memory pool along with // other vital statistics that define the memory pool. @@ -158,28 +155,28 @@ void gcode_M100() { // M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption. // This is useful to check the correctness of the M100 D and the M100 F commands. // -#if ENABLED(M100_FREE_MEMORY_CORRUPTOR) - if (code_seen('C')) { - int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool - SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); - ptr = (unsigned char*) __brkval; - SERIAL_ECHOPAIR("\n__brkval : ", ptr); - ptr += 8; - sp = top_of_stack(); - SERIAL_ECHOPAIR("\nStack Pointer : ", sp); - SERIAL_ECHOLNPGM("\n"); - n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that - // has altered the stack. - j = n / (x + 1); - for (i = 1; i <= x; i++) { - *(ptr + (i * j)) = i; - SERIAL_ECHOPGM("\nCorrupting address: 0x"); - prt_hex_word((unsigned int)(ptr + (i * j))); + #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) + if (code_seen('C')) { + int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool + SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); + ptr = (unsigned char*) __brkval; + SERIAL_ECHOPAIR("\n__brkval : ", ptr); + ptr += 8; + sp = top_of_stack(); + SERIAL_ECHOPAIR("\nStack Pointer : ", sp); + SERIAL_ECHOLNPGM("\n"); + n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that + // has altered the stack. + j = n / (x + 1); + for (i = 1; i <= x; i++) { + *(ptr + (i * j)) = i; + SERIAL_ECHOPGM("\nCorrupting address: 0x"); + prt_hex_word((unsigned int)(ptr + (i * j))); + } + SERIAL_ECHOLNPGM("\n"); + return; } - SERIAL_ECHOLNPGM("\n"); - return; - } -#endif + #endif // // M100 I Initializes the free memory pool so it can be watched and prints vital // statistics that define the free memory pool. From ee0983ab5791f6eb45c4d537a70e66cf61207e6d Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 9 Jul 2016 21:11:17 -0700 Subject: [PATCH 3/3] Further reduction when HOTENDS == 1 --- Marlin/Marlin_main.cpp | 19 ++++++----- Marlin/configuration_store.cpp | 16 ++++----- Marlin/dogm_lcd_implementation.h | 2 +- Marlin/temperature.cpp | 41 ++++++++++++++--------- Marlin/temperature.h | 56 ++++++++++++++++---------------- 5 files changed, 72 insertions(+), 62 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 38b69dab0d..89ab4615aa 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -4365,7 +4365,7 @@ inline void gcode_M104() { SERIAL_PROTOCOL_F(thermalManager.degTargetBed(), 1); #endif #if HOTENDS > 1 - for (int8_t e = 0; e < HOTENDS; ++e) { + HOTEND_LOOP() { SERIAL_PROTOCOLPGM(" T"); SERIAL_PROTOCOL(e); SERIAL_PROTOCOLCHAR(':'); @@ -4391,7 +4391,7 @@ inline void gcode_M104() { SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); #endif #if HOTENDS > 1 - for (int8_t e = 0; e < HOTENDS; ++e) { + HOTEND_LOOP() { SERIAL_PROTOCOLPGM(" @"); SERIAL_PROTOCOL(e); SERIAL_PROTOCOLCHAR(':'); @@ -4410,13 +4410,13 @@ inline void gcode_M104() { SERIAL_PROTOCOLPGM("C->"); SERIAL_PROTOCOL_F(thermalManager.rawBedTemp() / OVERSAMPLENR, 0); #endif - for (int8_t cur_hotend = 0; cur_hotend < HOTENDS; ++cur_hotend) { + HOTEND_LOOP() { SERIAL_PROTOCOLPGM(" T"); - SERIAL_PROTOCOL(cur_hotend); + SERIAL_PROTOCOL(e); SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL_F(thermalManager.degHotend(cur_hotend), 1); + SERIAL_PROTOCOL_F(thermalManager.degHotend(e), 1); SERIAL_PROTOCOLPGM("C->"); - SERIAL_PROTOCOL_F(thermalManager.rawHotendTemp(cur_hotend) / OVERSAMPLENR, 0); + SERIAL_PROTOCOL_F(thermalManager.rawHotendTemp(e) / OVERSAMPLENR, 0); } #endif } @@ -5436,7 +5436,7 @@ inline void gcode_M206() { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); - for (int e = 0; e < HOTENDS; e++) { + HOTEND_LOOP() { SERIAL_CHAR(' '); SERIAL_ECHO(hotend_offset[X_AXIS][e]); SERIAL_CHAR(','); @@ -7968,8 +7968,9 @@ void prepare_move_to_destination() { float max_temp = 0.0; if (ELAPSED(millis(), next_status_led_update_ms)) { next_status_led_update_ms += 500; // Update every 0.5s - for (int8_t cur_hotend = 0; cur_hotend < HOTENDS; ++cur_hotend) - max_temp = max(max(max_temp, thermalManager.degHotend(cur_hotend)), thermalManager.degTargetHotend(cur_hotend)); + HOTEND_LOOP() { + max_temp = max(max(max_temp, thermalManager.degHotend(e)), thermalManager.degTargetHotend(e)); + } #if HAS_TEMP_BED max_temp = max(max(max_temp, thermalManager.degTargetBed()), thermalManager.degBed()); #endif diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 4420a0e1f7..c14e957b22 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -618,7 +618,7 @@ void Config_ResetDefault() { #if ENABLED(PIDTEMP) #if ENABLED(PID_PARAMS_PER_HOTEND) - for (uint8_t e = 0; e < HOTENDS; e++) + HOTEND_LOOP #else int e = 0; UNUSED(e); // only need to write once #endif @@ -834,15 +834,15 @@ void Config_PrintSettings(bool forReplay) { #if ENABLED(PIDTEMP) #if HOTENDS > 1 if (forReplay) { - for (uint8_t i = 0; i < HOTENDS; i++) { + HOTEND_LOOP() { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M301 E", i); - SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, i)); - SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, i))); - SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, i))); + SERIAL_ECHOPAIR(" M301 E", e); + SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); + SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); #if ENABLED(PID_ADD_EXTRUSION_RATE) - SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, i)); - if (i == 0) SERIAL_ECHOPAIR(" L", lpq_len); + SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); + if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); #endif SERIAL_EOL; } diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index c71213a223..16c48e7be4 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -392,7 +392,7 @@ static void lcd_implementation_status_screen() { #endif // Extruders - for (int i = 0; i < HOTENDS; i++) _draw_heater_status(5 + i * 25, i); + HOTEND_LOOP() _draw_heater_status(5 + e * 25, e); // Heated bed #if HOTENDS < 4 && HAS_TEMP_BED diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 2fa6074b2c..f385cd212b 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -436,7 +436,7 @@ Temperature::Temperature() { } void Temperature::updatePID() { #if ENABLED(PIDTEMP) - for (int e = 0; e < HOTENDS; e++) { + HOTEND_LOOP() { temp_iState_max[e] = (PID_INTEGRAL_DRIVE_MAX) / PID_PARAM(Ki, e); #if ENABLED(PID_ADD_EXTRUSION_RATE) last_position[e] = 0; @@ -465,12 +465,12 @@ int Temperature::getHeaterPower(int heater) { EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN ? 2 : 3 }; uint8_t fanState = 0; - for (int f = 0; f < HOTENDS; f++) { - if (current_temperature[f] > EXTRUDER_AUTO_FAN_TEMPERATURE) - SBI(fanState, fanBit[f]); + HOTEND_LOOP() { + if (current_temperature[e] > EXTRUDER_AUTO_FAN_TEMPERATURE) + SBI(fanState, fanBit[e]); } uint8_t fanDone = 0; - for (int f = 0; f <= 3; f++) { + for (int8_t f = 0; f <= 3; f++) { int8_t pin = fanPin[f]; if (pin >= 0 && !TEST(fanDone, fanBit[f])) { unsigned char newFanSpeed = TEST(fanState, fanBit[f]) ? EXTRUDER_AUTO_FAN_SPEED : 0; @@ -507,10 +507,16 @@ void Temperature::_temp_error(int e, const char* serial_msg, const char* lcd_msg } void Temperature::max_temp_error(uint8_t e) { - _temp_error(e, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); + #if HOTENDS == 1 + UNUSED(e); + #endif + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); } void Temperature::min_temp_error(uint8_t e) { - _temp_error(e, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); + #if HOTENDS == 1 + UNUSED(e); + #endif + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); } float Temperature::get_pid_output(int e) { @@ -670,7 +676,7 @@ void Temperature::manage_heater() { #endif // Loop through all hotends - for (uint8_t e = 0; e < HOTENDS; e++) { + HOTEND_LOOP() { #if ENABLED(THERMAL_PROTECTION_HOTENDS) thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); @@ -877,7 +883,7 @@ void Temperature::updateTemperaturesFromRawValues() { #if ENABLED(HEATER_0_USES_MAX6675) current_temperature_raw[0] = read_max6675(); #endif - for (uint8_t e = 0; e < HOTENDS; e++) { + HOTEND_LOOP() { current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); } current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); @@ -931,7 +937,7 @@ void Temperature::init() { #endif // Finish init of mult hotend arrays - for (int e = 0; e < HOTENDS; e++) { + HOTEND_LOOP() { // populate with the first value maxttemp[e] = maxttemp[0]; #if ENABLED(PIDTEMP) @@ -1138,13 +1144,16 @@ void Temperature::init() { * their target temperature by a configurable margin. * This is called when the temperature is set. (M104, M109) */ - void Temperature::start_watching_heater(int e) { - if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { - watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE; - watch_heater_next_ms[e] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; + void Temperature::start_watching_heater(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + if (degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { + watch_target_temp[HOTEND_INDEX] = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE; + watch_heater_next_ms[HOTEND_INDEX] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; } else - watch_heater_next_ms[e] = 0; + watch_heater_next_ms[HOTEND_INDEX] = 0; } #endif @@ -1222,7 +1231,7 @@ void Temperature::init() { #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED void Temperature::disable_all_heaters() { - for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i); + HOTEND_LOOP() setTargetHotend(0, e); setTargetBed(0); // If all heaters go down then for sure our print job has stopped diff --git a/Marlin/temperature.h b/Marlin/temperature.h index f8b190800b..311fb4a39d 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -39,13 +39,13 @@ #endif #if HOTENDS == 1 - #define HOTEND_ARG 0 - #define HOTEND_INDEX 0 - #define EXTRUDER_ARG 0 + #define HOTEND_LOOP() const uint8_t e = 0; + #define HOTEND_INDEX 0 + #define EXTRUDER_IDX 0 #else - #define HOTEND_ARG hotend - #define HOTEND_INDEX e - #define EXTRUDER_ARG active_extruder + #define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) + #define HOTEND_INDEX e + #define EXTRUDER_IDX active_extruder #endif class Temperature { @@ -245,47 +245,47 @@ class Temperature { //inline so that there is no performance decrease. //deg=degreeCelsius - static float degHotend(uint8_t hotend) { + static float degHotend(uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - return current_temperature[HOTEND_ARG]; + return current_temperature[HOTEND_INDEX]; } static float degBed() { return current_temperature_bed; } #if ENABLED(SHOW_TEMP_ADC_VALUES) - static float rawHotendTemp(uint8_t hotend) { + static float rawHotendTemp(uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - return current_temperature_raw[HOTEND_ARG]; + return current_temperature_raw[HOTEND_INDEX]; } static float rawBedTemp() { return current_temperature_bed_raw; } #endif - static float degTargetHotend(uint8_t hotend) { + static float degTargetHotend(uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - return target_temperature[HOTEND_ARG]; + return target_temperature[HOTEND_INDEX]; } static float degTargetBed() { return target_temperature_bed; } #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 - static void start_watching_heater(int e = 0); + static void start_watching_heater(uint8_t e = 0); #endif #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 static void start_watching_bed(); #endif - static void setTargetHotend(const float& celsius, uint8_t hotend) { + static void setTargetHotend(const float& celsius, uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - target_temperature[HOTEND_ARG] = celsius; + target_temperature[HOTEND_INDEX] = celsius; #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 - start_watching_heater(HOTEND_ARG); + start_watching_heater(HOTEND_INDEX); #endif } @@ -296,19 +296,19 @@ class Temperature { #endif } - static bool isHeatingHotend(uint8_t hotend) { + static bool isHeatingHotend(uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - return target_temperature[HOTEND_ARG] > current_temperature[HOTEND_ARG]; + return target_temperature[HOTEND_INDEX] > current_temperature[HOTEND_INDEX]; } static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } - static bool isCoolingHotend(uint8_t hotend) { + static bool isCoolingHotend(uint8_t e) { #if HOTENDS == 1 - UNUSED(hotend); + UNUSED(e); #endif - return target_temperature[HOTEND_ARG] < current_temperature[HOTEND_ARG]; + return target_temperature[HOTEND_INDEX] < current_temperature[HOTEND_INDEX]; } static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } @@ -338,8 +338,8 @@ class Temperature { #if ENABLED(AUTOTEMP) if (planner.autotemp_enabled) { planner.autotemp_enabled = false; - if (degTargetHotend(EXTRUDER_ARG) > planner.autotemp_min) - setTargetHotend(0, EXTRUDER_ARG); + if (degTargetHotend(EXTRUDER_IDX) > planner.autotemp_min) + setTargetHotend(0, EXTRUDER_IDX); } #endif }