Fan tachometer support (#23086, #23180, #23199)

Co-Authored-By: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
Giuliano Zaro
2021-11-23 21:01:53 +01:00
committed by Scott Lahteine
parent 884308f964
commit af1d603374
21 changed files with 592 additions and 44 deletions

View File

@ -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
//

View File

@ -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();

View File

@ -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);