From 7671ff37a907d6f37fca29c436b299f2a8bb2c9f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 4 Apr 2022 21:29:49 +0200 Subject: [PATCH 1/4] Fix/optimize fan selftest Rewrite the part of the fan selftest to use a shared path between hotend and print fan. Remove the useless 10 seconds spin-up delay for the print fan. Reduce it to 5 seconds. Properly wait for readings after spin-up, so that RPMs are more reliable. Also tune the print fan threshold to a more reasonable default. Both, in conjunction, now avoid the "swapped fan" check that was incorrectly triggered in almost every case. --- Firmware/ultralcd.cpp | 166 +++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 91 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index eb75daecb..18a72e198 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -6658,15 +6658,15 @@ bool lcd_selftest() _progress = lcd_selftest_screen(TestScreen::ExtruderFan, _progress, 3, true, 2000); #if (defined(FANCHECK) && defined(TACH_0)) switch (lcd_selftest_fan_auto(0)){ // check extruder Fan - case FanCheck::ExtruderFan: - _result = false; - break; - case FanCheck::SwappedFan: - _swapped_fan = true; - // FALLTHRU - default: - _result = true; - break; + case FanCheck::SwappedFan: + _swapped_fan = true; // swapped is merely a hint (checked later) + // FALLTHRU + case FanCheck::Success: + _result = true; + break; + default: + _result = false; + break; } #else //defined(TACH_0) _result = lcd_selftest_manual_fan_check(0, false); @@ -6680,17 +6680,17 @@ bool lcd_selftest() { _progress = lcd_selftest_screen(TestScreen::PrintFan, _progress, 3, true, 2000); #if (defined(FANCHECK) && defined(TACH_1)) - switch (lcd_selftest_fan_auto(1)){ // check print fan - case FanCheck::PrintFan: - _result = false; - break; - case FanCheck::SwappedFan: - _swapped_fan = true; - // FALLTHRU - default: - _result = true; - break; - } + switch (lcd_selftest_fan_auto(1)){ // check print fan + case FanCheck::SwappedFan: + _swapped_fan = true; // swapped is merely a hint (checked later) + // FALLTHRU + case FanCheck::Success: + _result = true; + break; + default: + _result = false; + break; + } #else //defined(TACH_1) _result = lcd_selftest_manual_fan_check(1, false); #endif //defined(TACH_1) @@ -7574,90 +7574,74 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite, } #ifdef FANCHECK +// Set print fan speed +static void lcd_selftest_setfan(uint8_t speed) { + // set the fan speed + fanSpeed = speed; +#ifdef FAN_SOFT_PWM + fanSpeedSoftPwm = speed; +#endif + manage_heater(); +} + +// Wait for the specified number of seconds while displaying some single-character indicator on the +// screen coordinate col/row, then perform fan measurement +static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row, int n) { + // spin-up delay + static char symbols[] = {'-', '|'}; + static_assert(1000 / sizeof(symbols) * sizeof(symbols) == 1000); + while(delay--) { + for(uint8_t i = 0; i != sizeof(symbols); ++i) { + lcd_putc_at(col, row, symbols[i]); + delay_keep_alive(1000 / sizeof(symbols)); + } + } + +#ifdef FANCHECK + extruder_autofan_last_check = _millis(); +#endif + fan_measuring = true; + while(fan_measuring) { + delay_keep_alive(100); + } + + printf_P(PSTR("Test %d:\n"), n); + printf_P(PSTR("Print fan speed: %d\n"), fan_speed[1]); + printf_P(PSTR("Extr fan speed: %d\n"), fan_speed[0]); +} + static FanCheck lcd_selftest_fan_auto(int _fan) { + // speed threshold to differentiate between extruder and print fan + static const int printFanThr = 70; // >=4200 RPM + + // speed threshold to mark a fan as failed + static const int failThr = 20; // <1200 RPM would mean either a faulty Noctua, Altfan or print fan + switch (_fan) { case 0: - fanSpeed = 0; - manage_heater(); //turn off fan - setExtruderAutoFanState(3); //extruder fan -#ifdef FAN_SOFT_PWM - extruder_autofan_last_check = _millis(); - fan_measuring = true; -#endif //FAN_SOFT_PWM - _delay(2000); - setExtruderAutoFanState(0); //extruder fan - manage_heater(); //count average fan speed from 2s delay and turn off fans - - puts_P(PSTR("Test 1:")); - printf_P(PSTR("Print fan speed: %d\n"), fan_speed[1]); - printf_P(PSTR("Extr fan speed: %d\n"), fan_speed[0]); - - if (fan_speed[0] < 20) { // < 1200 RPM would mean either a faulty Noctua or Altfan + setExtruderAutoFanState(3); // extruder fan + lcd_selftest_setfan(0); // print fan off + lcd_selftest_measure_fans(2, 18, 2, 1); + setExtruderAutoFanState(0); // extruder fan off + if (fan_speed[0] < failThr) { return FanCheck::ExtruderFan; } -#ifdef FAN_SOFT_PWM - else if (fan_speed[0] > 50 ) { // printerFan is faster + if (fan_speed[0] >= printFanThr ) { return FanCheck::SwappedFan; } break; -#endif case 1: - //will it work with Thotend > 50 C ? -#ifdef FAN_SOFT_PWM - fanSpeed = 255; - fanSpeedSoftPwm = 255; - extruder_autofan_last_check = _millis(); //store time when measurement starts - fan_measuring = true; //start fan measuring, rest is on manage_heater -#else //FAN_SOFT_PWM - fanSpeed = 150; //print fan -#endif //FAN_SOFT_PWM - for (uint8_t i = 0; i < 5; i++) { - delay_keep_alive(1000); - lcd_putc_at(18, 3, '-'); - delay_keep_alive(1000); - lcd_putc_at(18, 3, '|'); - } - fanSpeed = 0; - -#ifdef FAN_SOFT_PWM - fanSpeedSoftPwm = 0; -#else //FAN_SOFT_PWM - manage_heater(); //turn off fan - manage_inactivity(true); //to turn off print fan -#endif //FAN_SOFT_PWM - puts_P(PSTR("Test 2:")); - printf_P(PSTR("Print fan speed: %d\n"), fan_speed[1]); - printf_P(PSTR("Extr fan speed: %d\n"), fan_speed[0]); - if (!fan_speed[1]) { - return FanCheck::PrintFan; - } - -#ifdef FAN_SOFT_PWM - fanSpeed = 80; - fanSpeedSoftPwm = 80; - - for (uint8_t i = 0; i < 5; i++) { - delay_keep_alive(1000); - lcd_putc_at(18, 3, '-'); - delay_keep_alive(1000); - lcd_putc_at(18, 3, '|'); - } - fanSpeed = 0; - - // noctua speed is between 17 and 24, turbine more then 30 - if (fan_speed[1] < 30) { + lcd_selftest_setfan(255); + lcd_selftest_measure_fans(5, 18, 3, 2); + lcd_selftest_setfan(0); + if (fan_speed[1] < failThr) { + return FanCheck::PrintFan; + } + if (fan_speed[1] < printFanThr) { return FanCheck::SwappedFan; } -#else - // fan is spinning, but measured RPM are too low for print fan, it must - // be left extruder fan - else if (fan_speed[1] < 34) { - return FanCheck::SwappedFan; - } -#endif //FAN_SOFT_PWM - break; } return FanCheck::Success; } From 859aa4d283c6dca8690e53ebe264a3a1e4ec988e Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 4 Apr 2022 23:29:52 +0200 Subject: [PATCH 2/4] Reuse M123 during fan selftest to report RPM M123 reports both fan speeds nicely in RPM, as well as the requested PWM for each so that we don't need to show the test "number" to distinguish between the two in the serial output. --- Firmware/ultralcd.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 18a72e198..b9b07d43e 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7586,7 +7586,7 @@ static void lcd_selftest_setfan(uint8_t speed) { // Wait for the specified number of seconds while displaying some single-character indicator on the // screen coordinate col/row, then perform fan measurement -static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row, int n) { +static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row) { // spin-up delay static char symbols[] = {'-', '|'}; static_assert(1000 / sizeof(symbols) * sizeof(symbols) == 1000); @@ -7605,9 +7605,7 @@ static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row, i delay_keep_alive(100); } - printf_P(PSTR("Test %d:\n"), n); - printf_P(PSTR("Print fan speed: %d\n"), fan_speed[1]); - printf_P(PSTR("Extr fan speed: %d\n"), fan_speed[0]); + gcode_M123(); } static FanCheck lcd_selftest_fan_auto(int _fan) @@ -7622,7 +7620,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan) case 0: setExtruderAutoFanState(3); // extruder fan lcd_selftest_setfan(0); // print fan off - lcd_selftest_measure_fans(2, 18, 2, 1); + lcd_selftest_measure_fans(2, 18, 2); setExtruderAutoFanState(0); // extruder fan off if (fan_speed[0] < failThr) { return FanCheck::ExtruderFan; @@ -7634,7 +7632,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan) case 1: lcd_selftest_setfan(255); - lcd_selftest_measure_fans(5, 18, 3, 2); + lcd_selftest_measure_fans(5, 18, 3); lcd_selftest_setfan(0); if (fan_speed[1] < failThr) { return FanCheck::PrintFan; From 765fbd3e92139a57ad09a5f90d8f8d9588391784 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 11 Apr 2022 17:42:31 +0200 Subject: [PATCH 3/4] Fix argument of lcd_selftest_fan_auto to be uint8_t --- Firmware/ultralcd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index b9b07d43e..83e3492a1 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -225,7 +225,7 @@ enum class FanCheck : uint_least8_t { * * @returns a TestError noerror, extruderFan, printFan or swappedFan. */ -static FanCheck lcd_selftest_fan_auto(int _fan); +static FanCheck lcd_selftest_fan_auto(uint8_t _fan); #endif //FANCHECK #ifdef PAT9125 @@ -7608,7 +7608,7 @@ static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row) { gcode_M123(); } -static FanCheck lcd_selftest_fan_auto(int _fan) +static FanCheck lcd_selftest_fan_auto(uint8_t _fan) { // speed threshold to differentiate between extruder and print fan static const int printFanThr = 70; // >=4200 RPM From 19b494a554b40dab2a6f04d689b692fd22e1f62a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 5 Jul 2022 09:02:47 +0200 Subject: [PATCH 4/4] Make the fan thresholds configurable --- Firmware/ultralcd.cpp | 4 ++-- Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 ++ Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 ++ 7 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 83e3492a1..f4784e32d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7611,10 +7611,10 @@ static void lcd_selftest_measure_fans(uint8_t delay, uint8_t col, uint8_t row) { static FanCheck lcd_selftest_fan_auto(uint8_t _fan) { // speed threshold to differentiate between extruder and print fan - static const int printFanThr = 70; // >=4200 RPM + static const int printFanThr = FANCHECK_AUTO_PRINT_FAN_THRS; // >= FANCHECK_AUTO_PRINT_FAN_THRS RPS // speed threshold to mark a fan as failed - static const int failThr = 20; // <1200 RPM would mean either a faulty Noctua, Altfan or print fan + static const int failThr = FANCHECK_AUTO_FAIL_THRS; // < FANCHECK_AUTO_FAIL_THRS RPM would mean either a faulty Noctua, Altfan or print fan switch (_fan) { case 0: diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index e26f5ea67..78ca60d12 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -219,6 +219,9 @@ #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan + /*------------------------------------ LOAD/UNLOAD FILAMENT SETTINGS diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 00c937db8..91e3084c4 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -220,6 +220,9 @@ #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan + /*------------------------------------ LOAD/UNLOAD FILAMENT SETTINGS diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index 7b7149baa..8b65364de 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -219,6 +219,9 @@ #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan + /*------------------------------------ LOAD/UNLOAD FILAMENT SETTINGS diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index 51644aaf4..47dbd1308 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -220,6 +220,9 @@ #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan + /*------------------------------------ LOAD/UNLOAD FILAMENT SETTINGS diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index dd4f1ffd2..03d1f697c 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -355,6 +355,8 @@ #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan /*------------------------------------ diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index dbc92ac06..33c196f18 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -359,6 +359,8 @@ #define EXTRUDER_ALTFAN_DETECT #define EXTRUDER_ALTFAN_SPEED_SILENT 128 +#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically +#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan /*------------------------------------