Co-Authored-By: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							884308f964
						
					
				
				
					commit
					af1d603374
				
			| @@ -603,6 +603,40 @@ | ||||
| #define COOLER_AUTO_FAN_TEMPERATURE 18 | ||||
| #define COOLER_AUTO_FAN_SPEED 255 | ||||
|  | ||||
| /** | ||||
|  * Hotend Cooling Fans tachometers | ||||
|  * | ||||
|  * Define one or more tachometer pins to enable fan speed | ||||
|  * monitoring, and reporting of fan speeds with M123. | ||||
|  * | ||||
|  * NOTE: Only works with fans up to 7000 RPM. | ||||
|  */ | ||||
| //#define FOURWIRES_FANS      // Needed with AUTO_FAN when 4-wire PWM fans are installed | ||||
| //#define E0_FAN_TACHO_PIN -1 | ||||
| //#define E0_FAN_TACHO_PULLUP | ||||
| //#define E0_FAN_TACHO_PULLDOWN | ||||
| //#define E1_FAN_TACHO_PIN -1 | ||||
| //#define E1_FAN_TACHO_PULLUP | ||||
| //#define E1_FAN_TACHO_PULLDOWN | ||||
| //#define E2_FAN_TACHO_PIN -1 | ||||
| //#define E2_FAN_TACHO_PULLUP | ||||
| //#define E2_FAN_TACHO_PULLDOWN | ||||
| //#define E3_FAN_TACHO_PIN -1 | ||||
| //#define E3_FAN_TACHO_PULLUP | ||||
| //#define E3_FAN_TACHO_PULLDOWN | ||||
| //#define E4_FAN_TACHO_PIN -1 | ||||
| //#define E4_FAN_TACHO_PULLUP | ||||
| //#define E4_FAN_TACHO_PULLDOWN | ||||
| //#define E5_FAN_TACHO_PIN -1 | ||||
| //#define E5_FAN_TACHO_PULLUP | ||||
| //#define E5_FAN_TACHO_PULLDOWN | ||||
| //#define E6_FAN_TACHO_PIN -1 | ||||
| //#define E6_FAN_TACHO_PULLUP | ||||
| //#define E6_FAN_TACHO_PULLDOWN | ||||
| //#define E7_FAN_TACHO_PIN -1 | ||||
| //#define E7_FAN_TACHO_PULLUP | ||||
| //#define E7_FAN_TACHO_PULLDOWN | ||||
|  | ||||
| /** | ||||
|  * Part-Cooling Fan Multiplexer | ||||
|  * | ||||
| @@ -3607,6 +3641,12 @@ | ||||
|  */ | ||||
| //#define CNC_COORDINATE_SYSTEMS | ||||
|  | ||||
| /** | ||||
|  * Auto-report fan speed with M123 S<seconds> | ||||
|  * Requires fans with tachometer pins | ||||
|  */ | ||||
| //#define AUTO_REPORT_FANS | ||||
|  | ||||
| /** | ||||
|  * Auto-report temperatures with M155 S<seconds> | ||||
|  */ | ||||
|   | ||||
| @@ -212,6 +212,10 @@ | ||||
|  | ||||
| #include "module/tool_change.h" | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|   #include "feature/fancheck.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(USE_CONTROLLER_FAN) | ||||
|   #include "feature/controllerfan.h" | ||||
| #endif | ||||
| @@ -832,6 +836,7 @@ void idle(bool no_stepper_sleep/*=false*/) { | ||||
|   #if HAS_AUTO_REPORTING | ||||
|     if (!gcode.autoreport_paused) { | ||||
|       TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_reporter.tick()); | ||||
|       TERN_(AUTO_REPORT_FANS, fan_check.auto_reporter.tick()); | ||||
|       TERN_(AUTO_REPORT_SD_STATUS, card.auto_reporter.tick()); | ||||
|       TERN_(AUTO_REPORT_POSITION, position_auto_reporter.tick()); | ||||
|       TERN_(BUFFER_MONITORING, queue.auto_report_buffer_statistics()); | ||||
| @@ -1278,6 +1283,8 @@ void setup() { | ||||
|     SETUP_RUN(controllerFan.setup()); | ||||
|   #endif | ||||
|  | ||||
|   TERN_(HAS_FANCHECK, fan_check.init()); | ||||
|  | ||||
|   // UI must be initialized before EEPROM | ||||
|   // (because EEPROM code calls the UI). | ||||
|  | ||||
|   | ||||
| @@ -140,6 +140,7 @@ | ||||
| #define STR_RESEND                          "Resend: " | ||||
| #define STR_UNKNOWN_COMMAND                 "Unknown command: \"" | ||||
| #define STR_ACTIVE_EXTRUDER                 "Active Extruder: " | ||||
| #define STR_ERR_FANSPEED                    "Fan speed E" | ||||
|  | ||||
| #define STR_PROBE_OFFSET                    "Probe Offset" | ||||
| #define STR_SKEW_MIN                        "min_skew_factor: " | ||||
|   | ||||
							
								
								
									
										207
									
								
								Marlin/src/feature/fancheck.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								Marlin/src/feature/fancheck.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,207 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * fancheck.cpp - fan tachometer check | ||||
|  */ | ||||
|  | ||||
| #include "../inc/MarlinConfig.h" | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|  | ||||
| #include "fancheck.h" | ||||
| #include "../module/temperature.h" | ||||
|  | ||||
| #if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 && DISABLED(FOURWIRES_FANS) | ||||
|   bool FanCheck::measuring = false; | ||||
| #endif | ||||
| bool FanCheck::tacho_state[TACHO_COUNT]; | ||||
| uint16_t FanCheck::edge_counter[TACHO_COUNT]; | ||||
| uint8_t FanCheck::rps[TACHO_COUNT]; | ||||
| FanCheck::TachoError FanCheck::error = FanCheck::TachoError::NONE; | ||||
| bool FanCheck::enabled; | ||||
|  | ||||
| void FanCheck::init() { | ||||
|   #define _TACHINIT(N) TERN(E##N##_FAN_TACHO_PULLUP, SET_INPUT_PULLUP, TERN(E##N##_FAN_TACHO_PULLDOWN, SET_INPUT_PULLDOWN, SET_INPUT))(E##N##_FAN_TACHO_PIN) | ||||
|   #if HAS_E0_FAN_TACHO | ||||
|     _TACHINIT(0); | ||||
|   #endif | ||||
|   #if HAS_E1_FAN_TACHO | ||||
|     _TACHINIT(1); | ||||
|   #endif | ||||
|   #if HAS_E2_FAN_TACHO | ||||
|     _TACHINIT(2); | ||||
|   #endif | ||||
|   #if HAS_E3_FAN_TACHO | ||||
|     _TACHINIT(3); | ||||
|   #endif | ||||
|   #if HAS_E4_FAN_TACHO | ||||
|     _TACHINIT(4); | ||||
|   #endif | ||||
|   #if HAS_E5_FAN_TACHO | ||||
|     _TACHINIT(5); | ||||
|   #endif | ||||
|   #if HAS_E6_FAN_TACHO | ||||
|     _TACHINIT(6); | ||||
|   #endif | ||||
|   #if HAS_E7_FAN_TACHO | ||||
|     _TACHINIT(7); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void FanCheck::update_tachometers() { | ||||
|   bool status; | ||||
|  | ||||
|   #define _TACHO_CASE(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break; | ||||
|   LOOP_L_N(f, TACHO_COUNT) { | ||||
|     switch (f) { | ||||
|       #if HAS_E0_FAN_TACHO | ||||
|         _TACHO_CASE(0) | ||||
|       #endif | ||||
|       #if HAS_E1_FAN_TACHO | ||||
|         _TACHO_CASE(1) | ||||
|       #endif | ||||
|       #if HAS_E2_FAN_TACHO | ||||
|         _TACHO_CASE(2) | ||||
|       #endif | ||||
|       #if HAS_E3_FAN_TACHO | ||||
|         _TACHO_CASE(3) | ||||
|       #endif | ||||
|       #if HAS_E4_FAN_TACHO | ||||
|         _TACHO_CASE(4) | ||||
|       #endif | ||||
|       #if HAS_E5_FAN_TACHO | ||||
|         _TACHO_CASE(5) | ||||
|       #endif | ||||
|       #if HAS_E6_FAN_TACHO | ||||
|         _TACHO_CASE(6) | ||||
|       #endif | ||||
|       #if HAS_E7_FAN_TACHO | ||||
|         _TACHO_CASE(7) | ||||
|       #endif | ||||
|       default: continue; | ||||
|     } | ||||
|  | ||||
|     if (status != tacho_state[f]) { | ||||
|       if (measuring) ++edge_counter[f]; | ||||
|       tacho_state[f] = status; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void FanCheck::compute_speed(uint16_t elapsedTime) { | ||||
|   static uint8_t errors_count[TACHO_COUNT]; | ||||
|   static uint8_t fan_reported_errors_msk = 0; | ||||
|  | ||||
|   uint8_t fan_error_msk = 0; | ||||
|   LOOP_L_N(f, TACHO_COUNT) { | ||||
|     switch (f) { | ||||
|       TERN_(HAS_E0_FAN_TACHO, case 0:) | ||||
|       TERN_(HAS_E1_FAN_TACHO, case 1:) | ||||
|       TERN_(HAS_E2_FAN_TACHO, case 2:) | ||||
|       TERN_(HAS_E3_FAN_TACHO, case 3:) | ||||
|       TERN_(HAS_E4_FAN_TACHO, case 4:) | ||||
|       TERN_(HAS_E5_FAN_TACHO, case 5:) | ||||
|       TERN_(HAS_E6_FAN_TACHO, case 6:) | ||||
|       TERN_(HAS_E7_FAN_TACHO, case 7:) | ||||
|         // Compute fan speed | ||||
|         rps[f] = edge_counter[f] * float(250) / elapsedTime; | ||||
|         edge_counter[f] = 0; | ||||
|  | ||||
|         // Check fan speed | ||||
|         constexpr int8_t max_extruder_fan_errors = TERN(HAS_PWMFANCHECK, 10000, 5000) / Temperature::fan_update_interval_ms; | ||||
|  | ||||
|         if (rps[f] >= 20 || TERN0(HAS_AUTO_FAN, thermalManager.autofan_speed[f] == 0)) | ||||
|           errors_count[f] = 0; | ||||
|         else if (errors_count[f] < max_extruder_fan_errors) | ||||
|           ++errors_count[f]; | ||||
|         else if (enabled) | ||||
|           SBI(fan_error_msk, f); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   // Drop the error when all fans are ok | ||||
|   if (!fan_error_msk && error == TachoError::REPORTED) error = TachoError::FIXED; | ||||
|  | ||||
|   if (error == TachoError::FIXED && !printJobOngoing() && !printingIsPaused()) { | ||||
|     error = TachoError::NONE; // if the issue has been fixed while the printer is idle, reenable immediately | ||||
|     ui.reset_alert_level(); | ||||
|   } | ||||
|  | ||||
|   if (fan_error_msk & ~fan_reported_errors_msk) { | ||||
|     // Handle new faults only | ||||
|     LOOP_L_N(f, TACHO_COUNT) if (TEST(fan_error_msk, f)) report_speed_error(f); | ||||
|   } | ||||
|   fan_reported_errors_msk = fan_error_msk; | ||||
| } | ||||
|  | ||||
| void FanCheck::report_speed_error(uint8_t fan) { | ||||
|   if (printJobOngoing()) { | ||||
|     if (error == TachoError::NONE) { | ||||
|       if (thermalManager.degTargetHotend(fan) != 0) { | ||||
|         kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)); | ||||
|         error = TachoError::REPORTED; | ||||
|       } | ||||
|       else | ||||
|         error = TachoError::DETECTED;   // Plans error for next processed command | ||||
|     } | ||||
|   } | ||||
|   else if (!printingIsPaused()) { | ||||
|     thermalManager.setTargetHotend(0, fan); // Always disable heating | ||||
|     if (error == TachoError::NONE) error = TachoError::REPORTED; | ||||
|   } | ||||
|  | ||||
|   SERIAL_ERROR_MSG(STR_ERR_FANSPEED, fan); | ||||
|   LCD_ALERTMESSAGE(MSG_FAN_SPEED_FAULT); | ||||
| } | ||||
|  | ||||
| void FanCheck::print_fan_states() { | ||||
|   LOOP_L_N(s, 2) { | ||||
|     LOOP_L_N(f, TACHO_COUNT) { | ||||
|       switch (f) { | ||||
|         TERN_(HAS_E0_FAN_TACHO, case 0:) | ||||
|         TERN_(HAS_E1_FAN_TACHO, case 1:) | ||||
|         TERN_(HAS_E2_FAN_TACHO, case 2:) | ||||
|         TERN_(HAS_E3_FAN_TACHO, case 3:) | ||||
|         TERN_(HAS_E4_FAN_TACHO, case 4:) | ||||
|         TERN_(HAS_E5_FAN_TACHO, case 5:) | ||||
|         TERN_(HAS_E6_FAN_TACHO, case 6:) | ||||
|         TERN_(HAS_E7_FAN_TACHO, case 7:) | ||||
|           SERIAL_ECHOPGM("E", f); | ||||
|           if (s == 0) | ||||
|             SERIAL_ECHOPGM(":", 60 * rps[f], " RPM "); | ||||
|           else | ||||
|             SERIAL_ECHOPGM("@:", TERN(HAS_AUTO_FAN, thermalManager.autofan_speed[f], 255), " "); | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   SERIAL_EOL(); | ||||
| } | ||||
|  | ||||
| #if ENABLED(AUTO_REPORT_FANS) | ||||
|   AutoReporter<FanCheck::AutoReportFan> FanCheck::auto_reporter; | ||||
|   void FanCheck::AutoReportFan::report() { print_fan_states(); } | ||||
| #endif | ||||
|  | ||||
| #endif // HAS_FANCHECK | ||||
							
								
								
									
										89
									
								
								Marlin/src/feature/fancheck.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Marlin/src/feature/fancheck.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "../inc/MarlinConfig.h" | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|  | ||||
| #include "../MarlinCore.h" | ||||
| #include "../lcd/marlinui.h" | ||||
|  | ||||
| #if ENABLED(AUTO_REPORT_FANS) | ||||
|   #include "../libs/autoreport.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|   #include "../gcode/queue.h" | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * fancheck.h | ||||
|  */ | ||||
| #define TACHO_COUNT TERN(HAS_E7_FAN_TACHO, 8, TERN(HAS_E6_FAN_TACHO, 7, TERN(HAS_E5_FAN_TACHO, 6, TERN(HAS_E4_FAN_TACHO, 5, TERN(HAS_E3_FAN_TACHO, 4, TERN(HAS_E2_FAN_TACHO, 3, TERN(HAS_E1_FAN_TACHO, 2, 1))))))) | ||||
|  | ||||
| class FanCheck { | ||||
|   private: | ||||
|  | ||||
|     enum class TachoError : uint8_t { NONE, DETECTED, REPORTED, FIXED }; | ||||
|  | ||||
|     #if HAS_PWMFANCHECK | ||||
|       static bool measuring;  // For future use (3 wires PWM controlled fans) | ||||
|     #else | ||||
|       static constexpr bool measuring = true; | ||||
|     #endif | ||||
|     static bool tacho_state[TACHO_COUNT]; | ||||
|     static uint16_t edge_counter[TACHO_COUNT]; | ||||
|     static uint8_t rps[TACHO_COUNT]; | ||||
|     static TachoError error; | ||||
|  | ||||
|     static inline void report_speed_error(uint8_t fan); | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     static bool enabled; | ||||
|  | ||||
|     static void init(); | ||||
|     static void update_tachometers(); | ||||
|     static void compute_speed(uint16_t elapsedTime); | ||||
|     static void print_fan_states(); | ||||
|     #if HAS_PWMFANCHECK | ||||
|       static inline void toggle_measuring() { measuring = !measuring; } | ||||
|       static inline bool is_measuring() { return measuring; } | ||||
|     #endif | ||||
|  | ||||
|     static inline void check_deferred_error() { | ||||
|       if (error == TachoError::DETECTED) { | ||||
|         error = TachoError::REPORTED; | ||||
|         TERN(PARK_HEAD_ON_PAUSE, queue.inject(F("M125")), kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT))); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     #if ENABLED(AUTO_REPORT_FANS) | ||||
|       struct AutoReportFan { static void report(); }; | ||||
|       static AutoReporter<AutoReportFan> auto_reporter; | ||||
|     #endif | ||||
| }; | ||||
|  | ||||
| extern FanCheck fan_check; | ||||
|  | ||||
| #endif // HAS_FANCHECK | ||||
| @@ -22,7 +22,7 @@ | ||||
|  | ||||
| #include "../gcode.h" | ||||
|  | ||||
| #include "../../lcd/marlinui.h" // for lcd_reset_alert_level | ||||
| #include "../../lcd/marlinui.h" // for ui.reset_alert_level | ||||
| #include "../../MarlinCore.h"   // for marlin_state | ||||
| #include "../queue.h"           // for flush_and_request_resend | ||||
|  | ||||
|   | ||||
| @@ -65,6 +65,10 @@ GcodeSuite gcode; | ||||
|   #include "../feature/password/password.h" | ||||
| #endif | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|   #include "../feature/fancheck.h" | ||||
| #endif | ||||
|  | ||||
| #include "../MarlinCore.h" // for idle, kill | ||||
|  | ||||
| // Inactivity shutdown | ||||
| @@ -296,6 +300,8 @@ void GcodeSuite::dwell(millis_t time) { | ||||
|  * Process the parsed command and dispatch it to its handler | ||||
|  */ | ||||
| void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { | ||||
|   TERN_(HAS_FANCHECK, fan_check.check_deferred_error()); | ||||
|  | ||||
|   KEEPALIVE_STATE(IN_HANDLER); | ||||
|  | ||||
|  /** | ||||
| @@ -577,6 +583,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { | ||||
|         case 113: M113(); break;                                  // M113: Set Host Keepalive interval | ||||
|       #endif | ||||
|  | ||||
|       #if HAS_FANCHECK | ||||
|         case 123: M123(); break;                                  // M123: Report fan states or set fans auto-report interval | ||||
|       #endif | ||||
|  | ||||
|       #if HAS_HEATED_BED | ||||
|         case 140: M140(); break;                                  // M140: Set bed temperature | ||||
|         case 190: M190(); break;                                  // M190: Wait for bed temperature to reach target | ||||
|   | ||||
| @@ -156,6 +156,7 @@ | ||||
|  * M121 - Disable endstops detection. | ||||
|  * | ||||
|  * M122 - Debug stepper (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470) | ||||
|  * M123 - Report fan tachometers. (Requires En_FAN_TACHO_PIN) Optionally set auto-report interval. (Requires AUTO_REPORT_FANS) | ||||
|  * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE) | ||||
|  * | ||||
|  * M126 - Solenoid Air Valve Open. (Requires BARICUDA) | ||||
| @@ -737,6 +738,10 @@ private: | ||||
|   static void M120(); | ||||
|   static void M121(); | ||||
|  | ||||
|   #if HAS_FANCHECK | ||||
|     static void M123(); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|     static void M125(); | ||||
|   #endif | ||||
|   | ||||
							
								
								
									
										48
									
								
								Marlin/src/gcode/temp/M123.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Marlin/src/gcode/temp/M123.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../inc/MarlinConfig.h" | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|  | ||||
| #include "../gcode.h" | ||||
| #include "../../feature/fancheck.h" | ||||
|  | ||||
| /** | ||||
|  * M123: Report fan states -or- set interval for auto-report | ||||
|  * | ||||
|  *   S<seconds> : Set auto-report interval | ||||
|  */ | ||||
| void GcodeSuite::M123() { | ||||
|  | ||||
|   #if ENABLED(AUTO_REPORT_FANS) | ||||
|     if (parser.seenval('S')) { | ||||
|       fan_check.auto_reporter.set_interval(parser.value_byte()); | ||||
|       return; | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   fan_check.print_fan_states(); | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // HAS_FANCHECK | ||||
| @@ -2510,10 +2510,42 @@ | ||||
|   #define AUTO_CHAMBER_IS_E 1 | ||||
| #endif | ||||
|  | ||||
| // Fans check | ||||
| #if HAS_HOTEND && PIN_EXISTS(E0_FAN_TACHO) | ||||
|   #define HAS_E0_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 1 && PIN_EXISTS(E1_FAN_TACHO) | ||||
|   #define HAS_E1_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 2 && PIN_EXISTS(E2_FAN_TACHO) | ||||
|   #define HAS_E2_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 3 && PIN_EXISTS(E3_FAN_TACHO) | ||||
|   #define HAS_E3_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 4 && PIN_EXISTS(E4_FAN_TACHO) | ||||
|   #define HAS_E4_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 5 && PIN_EXISTS(E5_FAN_TACHO) | ||||
|   #define HAS_E5_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 6 && PIN_EXISTS(E6_FAN_TACHO) | ||||
|   #define HAS_E6_FAN_TACHO 1 | ||||
| #endif | ||||
| #if HOTENDS > 7 && PIN_EXISTS(E7_FAN_TACHO) | ||||
|   #define HAS_E7_FAN_TACHO 1 | ||||
| #endif | ||||
| #if ANY(HAS_E0_FAN_TACHO, HAS_E1_FAN_TACHO, HAS_E2_FAN_TACHO, HAS_E3_FAN_TACHO, HAS_E4_FAN_TACHO, HAS_E5_FAN_TACHO, HAS_E6_FAN_TACHO, HAS_E7_FAN_TACHO) | ||||
|   #define HAS_FANCHECK 1 | ||||
|   #if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 && DISABLED(FOURWIRES_FANS) | ||||
|     #define HAS_PWMFANCHECK 1 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #if !HAS_TEMP_SENSOR | ||||
|   #undef AUTO_REPORT_TEMPERATURES | ||||
| #endif | ||||
| #if ANY(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS, AUTO_REPORT_POSITION) | ||||
| #if ANY(AUTO_REPORT_TEMPERATURES, AUTO_REPORT_SD_STATUS, AUTO_REPORT_POSITION, AUTO_REPORT_FANS) | ||||
|   #define HAS_AUTO_REPORTING 1 | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -2585,6 +2585,31 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Fan check | ||||
|  */ | ||||
| #if HAS_FANCHECK | ||||
|   #if BOTH(E0_FAN_TACHO_PULLUP, E0_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E0_FAN_TACHO_PULLUP or E0_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E1_FAN_TACHO_PULLUP, E1_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E1_FAN_TACHO_PULLUP or E1_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E2_FAN_TACHO_PULLUP, E2_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E2_FAN_TACHO_PULLUP or E2_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E3_FAN_TACHO_PULLUP, E3_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E3_FAN_TACHO_PULLUP or E3_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E4_FAN_TACHO_PULLUP, E4_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E4_FAN_TACHO_PULLUP or E4_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E5_FAN_TACHO_PULLUP, E5_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E5_FAN_TACHO_PULLUP or E5_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E6_FAN_TACHO_PULLUP, E6_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E6_FAN_TACHO_PULLUP or E6_FAN_TACHO_PULLDOWN." | ||||
|   #elif BOTH(E7_FAN_TACHO_PULLUP, E7_FAN_TACHO_PULLDOWN) | ||||
|     #error "Enable only one of E7_FAN_TACHO_PULLUP or E7_FAN_TACHO_PULLDOWN." | ||||
|   #endif | ||||
| #elif ENABLED(AUTO_REPORT_FANS) | ||||
|   #error "AUTO_REPORT_FANS requires one or more fans with a tachometer pin." | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Make sure only one EEPROM type is enabled | ||||
|  */ | ||||
|   | ||||
| @@ -570,6 +570,7 @@ namespace Language_en { | ||||
|   LSTR MSG_INFO_RUNAWAY_OFF               = _UxGT("Runaway Watch: OFF"); | ||||
|   LSTR MSG_INFO_RUNAWAY_ON                = _UxGT("Runaway Watch: ON"); | ||||
|   LSTR MSG_HOTEND_IDLE_TIMEOUT            = _UxGT("Hotend Idle Timeout"); | ||||
|   LSTR MSG_FAN_SPEED_FAULT                = _UxGT("Fan speed fault"); | ||||
|  | ||||
|   LSTR MSG_CASE_LIGHT                     = _UxGT("Case Light"); | ||||
|   LSTR MSG_CASE_LIGHT_BRIGHTNESS          = _UxGT("Light Brightness"); | ||||
| @@ -613,6 +614,7 @@ namespace Language_en { | ||||
|   LSTR MSG_RUNOUT_SENSOR                  = _UxGT("Runout Sensor"); | ||||
|   LSTR MSG_RUNOUT_DISTANCE_MM             = _UxGT("Runout Dist mm"); | ||||
|   LSTR MSG_RUNOUT_ENABLE                  = _UxGT("Enable Runout"); | ||||
|   LSTR MSG_FANCHECK                       = _UxGT("Fan Tacho Check"); | ||||
|   LSTR MSG_KILL_HOMING_FAILED             = _UxGT("Homing Failed"); | ||||
|   LSTR MSG_LCD_PROBING_FAILED             = _UxGT("Probing Failed"); | ||||
|  | ||||
|   | ||||
| @@ -556,6 +556,7 @@ namespace Language_it { | ||||
|   LSTR MSG_INFO_RUNAWAY_OFF               = _UxGT("Controllo fuga: OFF"); | ||||
|   LSTR MSG_INFO_RUNAWAY_ON                = _UxGT("Controllo fuga: ON"); | ||||
|   LSTR MSG_HOTEND_IDLE_TIMEOUT            = _UxGT("Timeout inatt.ugello"); | ||||
|   LSTR MSG_FAN_SPEED_FAULT                = _UxGT("Err.vel.della ventola"); | ||||
|  | ||||
|   LSTR MSG_CASE_LIGHT                     = _UxGT("Luci Case"); | ||||
|   LSTR MSG_CASE_LIGHT_BRIGHTNESS          = _UxGT("Luminosità Luci"); | ||||
| @@ -597,6 +598,8 @@ namespace Language_it { | ||||
|   LSTR MSG_FILAMENT_CHANGE_NOZZLE         = _UxGT("  Ugello: "); | ||||
|   LSTR MSG_RUNOUT_SENSOR                  = _UxGT("Sens.filo termin.");  // Max 17 characters | ||||
|   LSTR MSG_RUNOUT_DISTANCE_MM             = _UxGT("Dist mm filo term."); | ||||
|   LSTR MSG_RUNOUT_ENABLE                  = _UxGT("Abil.filo termin."); | ||||
|   LSTR MSG_FANCHECK                       = _UxGT("Verif.tacho vent.");  // Max 17 characters | ||||
|   LSTR MSG_KILL_HOMING_FAILED             = _UxGT("Home fallito"); | ||||
|   LSTR MSG_LCD_PROBING_FAILED             = _UxGT("Sondaggio fallito"); | ||||
|  | ||||
|   | ||||
| @@ -1566,10 +1566,6 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | ||||
|     TERN_(HAS_LCD_MENU, return_to_status()); | ||||
|   } | ||||
|  | ||||
|   #if ANY(PARK_HEAD_ON_PAUSE, SDSUPPORT) | ||||
|     #include "../gcode/queue.h" | ||||
|   #endif | ||||
|  | ||||
|   void MarlinUI::pause_print() { | ||||
|     #if HAS_LCD_MENU | ||||
|       synchronize(GET_TEXT(MSG_PAUSING)); | ||||
|   | ||||
| @@ -34,6 +34,10 @@ | ||||
|   #include "../../feature/runout.h" | ||||
| #endif | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|   #include "../../feature/fancheck.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../../feature/powerloss.h" | ||||
| #endif | ||||
| @@ -537,6 +541,10 @@ void menu_configuration() { | ||||
|     EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_FANCHECK | ||||
|     EDIT_ITEM(bool, MSG_FANCHECK, &fan_check.enabled); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     EDIT_ITEM(bool, MSG_OUTAGE_RECOVERY, &recovery.enabled, recovery.changed); | ||||
|   #endif | ||||
|   | ||||
| @@ -154,6 +154,10 @@ | ||||
|   #include "../libs/buzzer.h" | ||||
| #endif | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|   #include "../feature/fancheck.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(DGUS_LCD_UI_MKS) | ||||
|   #include "../lcd/extui/dgus/DGUSScreenHandler.h" | ||||
|   #include "../lcd/extui/dgus/DGUSDisplayDef.h" | ||||
| @@ -491,6 +495,13 @@ typedef struct SettingsDataStruct { | ||||
|     bool buzzer_enabled; | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // Fan tachometer check | ||||
|   // | ||||
|   #if HAS_FANCHECK | ||||
|     bool fan_check_enabled; | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // MKS UI controller | ||||
|   // | ||||
| @@ -1433,6 +1444,13 @@ void MarlinSettings::postprocess() { | ||||
|       EEPROM_WRITE(ui.buzzer_enabled); | ||||
|     #endif | ||||
|  | ||||
|     // | ||||
|     // Fan tachometer check | ||||
|     // | ||||
|     #if HAS_FANCHECK | ||||
|       EEPROM_WRITE(fan_check.enabled); | ||||
|     #endif | ||||
|  | ||||
|     // | ||||
|     // MKS UI controller | ||||
|     // | ||||
| @@ -2339,6 +2357,14 @@ void MarlinSettings::postprocess() { | ||||
|         EEPROM_READ(ui.buzzer_enabled); | ||||
|       #endif | ||||
|  | ||||
|       // | ||||
|       // Fan tachometer check | ||||
|       // | ||||
|       #if HAS_FANCHECK | ||||
|         _FIELD_TEST(fan_check_enabled); | ||||
|         EEPROM_READ(fan_check.enabled); | ||||
|       #endif | ||||
|  | ||||
|       // | ||||
|       // MKS UI controller | ||||
|       // | ||||
| @@ -3036,6 +3062,11 @@ void MarlinSettings::reset() { | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // Fan tachometer check | ||||
|   // | ||||
|   TERN_(HAS_FANCHECK, fan_check.enabled = true); | ||||
|  | ||||
|   // | ||||
|   // MKS UI controller | ||||
|   // | ||||
|   | ||||
| @@ -298,7 +298,7 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); | ||||
|   redundant_info_t Temperature::temp_redundant; | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(AUTO_POWER_E_FANS) | ||||
| #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) | ||||
|   uint8_t Temperature::autofan_speed[HOTENDS]; // = { 0 } | ||||
| #endif | ||||
|  | ||||
| @@ -530,8 +530,9 @@ volatile bool Temperature::raw_temps_ready = false; | ||||
|   millis_t Temperature::preheat_end_time[HOTENDS] = { 0 }; | ||||
| #endif | ||||
|  | ||||
| #if HAS_AUTO_FAN | ||||
|   millis_t Temperature::next_auto_fan_check_ms = 0; | ||||
| #if HAS_FAN_LOGIC | ||||
|   constexpr millis_t Temperature::fan_update_interval_ms; | ||||
|   millis_t Temperature::fan_update_ms = 0; | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(FAN_SOFT_PWM) | ||||
| @@ -618,7 +619,7 @@ volatile bool Temperature::raw_temps_ready = false; | ||||
|       bool heated = false; | ||||
|     #endif | ||||
|  | ||||
|     TERN_(HAS_AUTO_FAN, next_auto_fan_check_ms = next_temp_ms + 2500UL); | ||||
|     TERN_(HAS_FAN_LOGIC, fan_update_ms = next_temp_ms + fan_update_interval_ms); | ||||
|  | ||||
|     TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_STARTED)); | ||||
|     TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START)); | ||||
| @@ -663,12 +664,7 @@ volatile bool Temperature::raw_temps_ready = false; | ||||
|           ONHEATING(start_temp, current_temp, target); | ||||
|         #endif | ||||
|  | ||||
|         #if HAS_AUTO_FAN | ||||
|           if (ELAPSED(ms, next_auto_fan_check_ms)) { | ||||
|             checkExtruderAutoFans(); | ||||
|             next_auto_fan_check_ms = ms + 2500UL; | ||||
|           } | ||||
|         #endif | ||||
|         TERN_(HAS_FAN_LOGIC, manage_extruder_fans(ms)); | ||||
|  | ||||
|         if (heating && current_temp > target && ELAPSED(ms, t2 + 5000UL)) { | ||||
|           heating = false; | ||||
| @@ -857,6 +853,7 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { | ||||
| #define _EFANOVERLAP(A,B) _FANOVERLAP(E##A,B) | ||||
|  | ||||
| #if HAS_AUTO_FAN | ||||
|  | ||||
|   #if EXTRUDER_AUTO_FAN_SPEED != 255 | ||||
|     #define INIT_E_AUTO_FAN_PIN(P) do{ if (P == FAN1_PIN || P == FAN2_PIN) { SET_PWM(P); SET_FAST_PWM_FREQ(P); } else SET_OUTPUT(P); }while(0) | ||||
|   #else | ||||
| @@ -870,7 +867,7 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { | ||||
|  | ||||
|   #define CHAMBER_FAN_INDEX HOTENDS | ||||
|  | ||||
|   void Temperature::checkExtruderAutoFans() { | ||||
|   void Temperature::update_autofans() { | ||||
|     #define _EFAN(B,A) _EFANOVERLAP(A,B) ? B : | ||||
|     static const uint8_t fanBit[] PROGMEM = { | ||||
|       0 | ||||
| @@ -930,36 +927,43 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { | ||||
|             break; | ||||
|         #endif | ||||
|         default: | ||||
|           #if ENABLED(AUTO_POWER_E_FANS) | ||||
|           #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) | ||||
|             autofan_speed[realFan] = fan_on ? EXTRUDER_AUTO_FAN_SPEED : 0; | ||||
|           #endif | ||||
|           break; | ||||
|       } | ||||
|  | ||||
|       #if BOTH(HAS_FANCHECK, HAS_PWMFANCHECK) | ||||
|         #define _AUTOFAN_SPEED() fan_check.is_measuring() ? 255 : EXTRUDER_AUTO_FAN_SPEED | ||||
|       #else | ||||
|         #define _AUTOFAN_SPEED() EXTRUDER_AUTO_FAN_SPEED | ||||
|       #endif | ||||
|       #define _AUTOFAN_CASE(N) case N: _UPDATE_AUTO_FAN(E##N, fan_on, _AUTOFAN_SPEED()); break | ||||
|  | ||||
|       switch (f) { | ||||
|         #if HAS_AUTO_FAN_0 | ||||
|           case 0: _UPDATE_AUTO_FAN(E0, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(0); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_1 | ||||
|           case 1: _UPDATE_AUTO_FAN(E1, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(1); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_2 | ||||
|           case 2: _UPDATE_AUTO_FAN(E2, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(2); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_3 | ||||
|           case 3: _UPDATE_AUTO_FAN(E3, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(3); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_4 | ||||
|           case 4: _UPDATE_AUTO_FAN(E4, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(4); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_5 | ||||
|           case 5: _UPDATE_AUTO_FAN(E5, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(5); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_6 | ||||
|           case 6: _UPDATE_AUTO_FAN(E6, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(6); | ||||
|         #endif | ||||
|         #if HAS_AUTO_FAN_7 | ||||
|           case 7: _UPDATE_AUTO_FAN(E7, fan_on, EXTRUDER_AUTO_FAN_SPEED); break; | ||||
|           _AUTOFAN_CASE(7); | ||||
|         #endif | ||||
|         #if HAS_AUTO_CHAMBER_FAN && !AUTO_CHAMBER_IS_E | ||||
|           case CHAMBER_FAN_INDEX: _UPDATE_AUTO_FAN(CHAMBER, fan_on, CHAMBER_AUTO_FAN_SPEED); break; | ||||
| @@ -1391,20 +1395,14 @@ void Temperature::manage_heater() { | ||||
|       _temp_error((heater_id_t)HEATER_ID(TEMP_SENSOR_REDUNDANT_TARGET), F(STR_REDUNDANCY), GET_TEXT_F(MSG_ERR_REDUNDANT_TEMP)); | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_AUTO_FAN | ||||
|     if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently | ||||
|       checkExtruderAutoFans(); | ||||
|       next_auto_fan_check_ms = ms + 2500UL; | ||||
|     } | ||||
|   #endif | ||||
|   // Manage extruder auto fans and/or read fan tachometers | ||||
|   TERN_(HAS_FAN_LOGIC, manage_extruder_fans(ms)); | ||||
|  | ||||
|   #if ENABLED(FILAMENT_WIDTH_SENSOR) | ||||
|     /** | ||||
|      * Dynamically set the volumetric multiplier based | ||||
|      * on the delayed Filament Width measurement. | ||||
|      */ | ||||
|     filwidth.update_volumetric(); | ||||
|   #endif | ||||
|   /** | ||||
|    * Dynamically set the volumetric multiplier based | ||||
|    * on the delayed Filament Width measurement. | ||||
|    */ | ||||
|   TERN_(FILAMENT_WIDTH_SENSOR, filwidth.update_volumetric()); | ||||
|  | ||||
|   #if HAS_HEATED_BED | ||||
|  | ||||
| @@ -3525,6 +3523,9 @@ void Temperature::isr() { | ||||
|     babystep.task(); | ||||
|   #endif | ||||
|  | ||||
|   // Check fan tachometers | ||||
|   TERN_(HAS_FANCHECK, fan_check.update_tachometers()); | ||||
|  | ||||
|   // Poll endstops state, if required | ||||
|   endstops.poll(); | ||||
|  | ||||
|   | ||||
| @@ -37,6 +37,10 @@ | ||||
|   #include "../libs/autoreport.h" | ||||
| #endif | ||||
|  | ||||
| #if HAS_FANCHECK | ||||
|   #include "../feature/fancheck.h" | ||||
| #endif | ||||
|  | ||||
| #ifndef SOFT_PWM_SCALE | ||||
|   #define SOFT_PWM_SCALE 0 | ||||
| #endif | ||||
| @@ -344,6 +348,10 @@ typedef struct { int16_t raw_min, raw_max; celsius_t mintemp, maxtemp; } temp_ra | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if HAS_AUTO_FAN || HAS_FANCHECK | ||||
|   #define HAS_FAN_LOGIC 1 | ||||
| #endif | ||||
|  | ||||
| class Temperature { | ||||
|  | ||||
|   public: | ||||
| @@ -372,7 +380,7 @@ class Temperature { | ||||
|       static redundant_info_t temp_redundant; | ||||
|     #endif | ||||
|  | ||||
|     #if ENABLED(AUTO_POWER_E_FANS) | ||||
|     #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) | ||||
|       static uint8_t autofan_speed[HOTENDS]; | ||||
|     #endif | ||||
|     #if ENABLED(AUTO_POWER_CHAMBER_FAN) | ||||
| @@ -459,6 +467,10 @@ class Temperature { | ||||
|       static int16_t lpq_len; | ||||
|     #endif | ||||
|  | ||||
|     #if HAS_FAN_LOGIC | ||||
|       static constexpr millis_t fan_update_interval_ms = TERN(HAS_PWMFANCHECK, 5000, TERN(HAS_FANCHECK, 1000, 2500)); | ||||
|     #endif | ||||
|  | ||||
|   private: | ||||
|  | ||||
|     #if ENABLED(WATCH_HOTENDS) | ||||
| @@ -510,8 +522,28 @@ class Temperature { | ||||
|       static millis_t preheat_end_time[HOTENDS]; | ||||
|     #endif | ||||
|  | ||||
|     #if HAS_AUTO_FAN | ||||
|       static millis_t next_auto_fan_check_ms; | ||||
|     #if HAS_FAN_LOGIC | ||||
|       static millis_t fan_update_ms; | ||||
|  | ||||
|       static inline void manage_extruder_fans(millis_t ms) { | ||||
|         if (ELAPSED(ms, fan_update_ms)) { // only need to check fan state very infrequently | ||||
|           const millis_t next_ms = ms + fan_update_interval_ms; | ||||
|           #if HAS_PWMFANCHECK | ||||
|             #define FAN_CHECK_DURATION 100 | ||||
|             if (fan_check.is_measuring()) { | ||||
|               fan_check.compute_speed(ms + FAN_CHECK_DURATION - fan_update_ms); | ||||
|               fan_update_ms = next_ms; | ||||
|             } | ||||
|             else | ||||
|               fan_update_ms = ms + FAN_CHECK_DURATION; | ||||
|             fan_check.toggle_measuring(); | ||||
|           #else | ||||
|             TERN_(HAS_FANCHECK, fan_check.compute_speed(next_ms - fan_update_ms)); | ||||
|             fan_update_ms = next_ms; | ||||
|           #endif | ||||
|           TERN_(HAS_AUTO_FAN, update_autofans()); // Needed as last when HAS_PWMFANCHECK to properly force fan speed | ||||
|         } | ||||
|       } | ||||
|     #endif | ||||
|  | ||||
|     #if ENABLED(PROBING_HEATERS_OFF) | ||||
| @@ -961,7 +993,7 @@ class Temperature { | ||||
|       static int16_t read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0)); | ||||
|     #endif | ||||
|  | ||||
|     static void checkExtruderAutoFans(); | ||||
|     static void update_autofans(); | ||||
|  | ||||
|     #if HAS_HOTEND | ||||
|       static float get_pid_output_hotend(const uint8_t e); | ||||
|   | ||||
| @@ -188,6 +188,14 @@ | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #ifndef E0_FAN_TACHO_PIN | ||||
|   #ifdef MK3_FAN_PINS | ||||
|     #define E0_FAN_TACHO_PIN                PE1   // Fan1 | ||||
|   #else | ||||
|     #define E0_FAN_TACHO_PIN                PE0   // Fan0 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * -----------------------------------BTT002 V1.0---------------------------------------- | ||||
|  *               ------                                          ------                  | | ||||
|   | ||||
| @@ -108,6 +108,7 @@ CANCEL_OBJECTS                         = src_filter=+<src/feature/cancel_object. | ||||
| CASE_LIGHT_ENABLE                      = src_filter=+<src/feature/caselight.cpp> +<src/gcode/feature/caselight> | ||||
| EXTERNAL_CLOSED_LOOP_CONTROLLER        = src_filter=+<src/feature/closedloop.cpp> +<src/gcode/calibrate/M12.cpp> | ||||
| USE_CONTROLLER_FAN                     = src_filter=+<src/feature/controllerfan.cpp> | ||||
| HAS_COOLER|LASER_COOLANT_FLOW_METER    = src_filter=+<src/feature/cooler.cpp> | ||||
| HAS_MOTOR_CURRENT_DAC                  = src_filter=+<src/feature/dac> | ||||
| DIRECT_STEPPING                        = src_filter=+<src/feature/direct_stepping.cpp> +<src/gcode/motion/G6.cpp> | ||||
| EMERGENCY_PARSER                       = src_filter=+<src/feature/e_parser.cpp> -<src/gcode/control/M108_*.cpp> | ||||
| @@ -115,6 +116,7 @@ I2C_POSITION_ENCODERS                  = src_filter=+<src/feature/encoder_i2c.cp | ||||
| IIC_BL24CXX_EEPROM                     = src_filter=+<src/libs/BL24CXX.cpp> | ||||
| HAS_SPI_FLASH                          = src_filter=+<src/libs/W25Qxx.cpp> | ||||
| HAS_ETHERNET                           = src_filter=+<src/feature/ethernet.cpp> +<src/gcode/feature/network/M552-M554.cpp> | ||||
| HAS_FANCHECK                           = src_filter=+<src/feature/fancheck.cpp> +<src/gcode/temp/M123.cpp> | ||||
| HAS_FANMUX                             = src_filter=+<src/feature/fanmux.cpp> | ||||
| FILAMENT_WIDTH_SENSOR                  = src_filter=+<src/feature/filwidth.cpp> +<src/gcode/feature/filwidth> | ||||
| FWRETRACT                              = src_filter=+<src/feature/fwretract.cpp> +<src/gcode/feature/fwretract> | ||||
| @@ -212,7 +214,6 @@ GCODE_REPEAT_MARKERS                   = src_filter=+<src/feature/repeat.cpp> +< | ||||
| HAS_EXTRUDERS                          = src_filter=+<src/gcode/units/M82_M83.cpp> +<src/gcode/temp/M104_M109.cpp> +<src/gcode/config/M221.cpp> | ||||
| HAS_TEMP_PROBE                         = src_filter=+<src/gcode/temp/M192.cpp> | ||||
| HAS_COOLER                             = src_filter=+<src/gcode/temp/M143_M193.cpp> | ||||
| HAS_COOLER|LASER_COOLANT_FLOW_METER    = src_filter=+<src/feature/cooler.cpp> | ||||
| AUTO_REPORT_TEMPERATURES               = src_filter=+<src/gcode/temp/M155.cpp> | ||||
| INCH_MODE_SUPPORT                      = src_filter=+<src/gcode/units/G20_G21.cpp> | ||||
| TEMPERATURE_UNITS_SUPPORT              = src_filter=+<src/gcode/units/M149.cpp> | ||||
|   | ||||
| @@ -112,6 +112,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared> | ||||
|   -<src/feature/e_parser.cpp> | ||||
|   -<src/feature/encoder_i2c.cpp> | ||||
|   -<src/feature/ethernet.cpp> -<src/gcode/feature/network/M552-M554.cpp> | ||||
|   -<src/feature/fancheck.cpp> | ||||
|   -<src/feature/fanmux.cpp> | ||||
|   -<src/feature/filwidth.cpp> -<src/gcode/feature/filwidth> | ||||
|   -<src/feature/fwretract.cpp> -<src/gcode/feature/fwretract> | ||||
| @@ -229,6 +230,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared> | ||||
|   -<src/gcode/sd/M32.cpp> | ||||
|   -<src/gcode/sd/M808.cpp> | ||||
|   -<src/gcode/temp/M104_M109.cpp> | ||||
|   -<src/gcode/temp/M123.cpp> | ||||
|   -<src/gcode/temp/M155.cpp> | ||||
|   -<src/gcode/temp/M192.cpp> | ||||
|   -<src/gcode/units/G20_G21.cpp> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user