From 8ccfb606c0c9e56cd45539fd4fa7dec9b39a6dfc Mon Sep 17 00:00:00 2001 From: Daniel Kaufman Date: Tue, 3 Oct 2023 12:42:51 -0500 Subject: [PATCH 1/3] added the max fan pct to the PWM-Fan usermod. This allows high speed (loud fans) like delta fans to cap at a maximum percentage to keep noise down. --- usermods/PWM_fan/usermod_PWM_fan.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h index f7fe0e10..ba41f343 100644 --- a/usermods/PWM_fan/usermod_PWM_fan.h +++ b/usermods/PWM_fan/usermod_PWM_fan.h @@ -52,6 +52,7 @@ class PWMFanUsermod : public Usermod { uint8_t tachoUpdateSec = 30; float targetTemperature = 35.0; uint8_t minPWMValuePct = 0; + uint8_t maxPWMValuePct = 100; uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups. uint8_t pwmValuePct = 0; @@ -63,6 +64,7 @@ class PWMFanUsermod : public Usermod { static const char _temperature[]; static const char _tachoUpdateSec[]; static const char _minPWMValuePct[]; + static const char _maxPWMValuePct[]; static const char _IRQperRotation[]; static const char _speed[]; static const char _lock[]; @@ -159,7 +161,7 @@ class PWMFanUsermod : public Usermod { float difftemp = temp - targetTemperature; // Default to run fan at full speed. int newPWMvalue = 255; - int pwmStep = ((100 - minPWMValuePct) * newPWMvalue) / (7*100); + int pwmStep = ((maxPWMValuePct - minPWMValuePct) * newPWMvalue) / (7*100); int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100; if ((temp == NAN) || (temp <= -100.0)) { @@ -312,6 +314,7 @@ class PWMFanUsermod : public Usermod { top[FPSTR(_tachoUpdateSec)] = tachoUpdateSec; top[FPSTR(_temperature)] = targetTemperature; top[FPSTR(_minPWMValuePct)] = minPWMValuePct; + top[FPSTR(_maxPWMValuePct)] = maxPWMValuePct; top[FPSTR(_IRQperRotation)] = numberOfInterrupsInOneSingleRotation; DEBUG_PRINTLN(F("Autosave config saved.")); } @@ -345,6 +348,8 @@ class PWMFanUsermod : public Usermod { targetTemperature = top[FPSTR(_temperature)] | targetTemperature; minPWMValuePct = top[FPSTR(_minPWMValuePct)] | minPWMValuePct; minPWMValuePct = (uint8_t) min(100,max(0,(int)minPWMValuePct)); // bounds checking + maxPWMValuePct = top[FPSTR(_maxPWMValuePct)] | maxPWMValuePct; + maxPWMValuePct = (uint8_t) min(100,max((int)minPWMValuePct,(int)maxPWMValuePct)); // bounds checking numberOfInterrupsInOneSingleRotation = top[FPSTR(_IRQperRotation)] | numberOfInterrupsInOneSingleRotation; numberOfInterrupsInOneSingleRotation = (uint8_t) max(1,(int)numberOfInterrupsInOneSingleRotation); // bounds checking @@ -389,6 +394,7 @@ const char PWMFanUsermod::_pwmPin[] PROGMEM = "PWM-pin"; const char PWMFanUsermod::_temperature[] PROGMEM = "target-temp-C"; const char PWMFanUsermod::_tachoUpdateSec[] PROGMEM = "tacho-update-s"; const char PWMFanUsermod::_minPWMValuePct[] PROGMEM = "min-PWM-percent"; +const char PWMFanUsermod::_maxPWMValuePct[] PROGMEM = "max-PWM-percent"; const char PWMFanUsermod::_IRQperRotation[] PROGMEM = "IRQs-per-rotation"; const char PWMFanUsermod::_speed[] PROGMEM = "speed"; const char PWMFanUsermod::_lock[] PROGMEM = "lock"; From b56490650c8aa7e3ddc67b41cf0aab29645c2bda Mon Sep 17 00:00:00 2001 From: Daniel Kaufman Date: Thu, 5 Oct 2023 00:37:51 -0500 Subject: [PATCH 2/3] fix for maxPWMValuePct being ignored --- usermods/PWM_fan/usermod_PWM_fan.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h index ba41f343..790b8fc9 100644 --- a/usermods/PWM_fan/usermod_PWM_fan.h +++ b/usermods/PWM_fan/usermod_PWM_fan.h @@ -159,7 +159,7 @@ class PWMFanUsermod : public Usermod { void setFanPWMbasedOnTemperature(void) { float temp = getActualTemperature(); float difftemp = temp - targetTemperature; - // Default to run fan at full speed. + // Default to run fan at full speed (or maxPWMPct Defined by the user). int newPWMvalue = 255; int pwmStep = ((maxPWMValuePct - minPWMValuePct) * newPWMvalue) / (7*100); int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100; @@ -181,6 +181,8 @@ class PWMFanUsermod : public Usermod { newPWMvalue = pwmMinimumValue + 5*pwmStep; } else if (difftemp <= 3.0) { newPWMvalue = pwmMinimumValue + 6*pwmStep; + } else { + newPWMvalue = pwmMinimumValue + 7*pwmStep; } updateFanSpeed(newPWMvalue); } From 86300a8e3ccdd2d4ea3c31ddd55a5deb60080c08 Mon Sep 17 00:00:00 2001 From: Daniel Kaufman Date: Thu, 5 Oct 2023 09:49:00 -0500 Subject: [PATCH 3/3] code review suggestions to make the code more efficient and cleaner --- usermods/PWM_fan/usermod_PWM_fan.h | 45 ++++++++++++++---------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h index 790b8fc9..05b6d9b3 100644 --- a/usermods/PWM_fan/usermod_PWM_fan.h +++ b/usermods/PWM_fan/usermod_PWM_fan.h @@ -56,6 +56,11 @@ class PWMFanUsermod : public Usermod { uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups. uint8_t pwmValuePct = 0; + // constant values + static const uint8_t _pwmMaxValue = 255; + static const uint8_t _pwmMaxStepCount = 7; + float _pwmTempStepSize = 0.5f; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _enabled[]; @@ -158,33 +163,25 @@ class PWMFanUsermod : public Usermod { void setFanPWMbasedOnTemperature(void) { float temp = getActualTemperature(); - float difftemp = temp - targetTemperature; - // Default to run fan at full speed (or maxPWMPct Defined by the user). - int newPWMvalue = 255; - int pwmStep = ((maxPWMValuePct - minPWMValuePct) * newPWMvalue) / (7*100); - int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100; + // dividing minPercent and maxPercent into equal pwmvalue sizes + int pwmStepSize = ((maxPWMValuePct - minPWMValuePct) * _pwmMaxValue) / (_pwmMaxStepCount*100); + int pwmStep = calculatePwmStep(temp - targetTemperature); + // minimum based on full speed - not entered MaxPercent + int pwmMinimumValue = (minPWMValuePct * _pwmMaxValue) / 100; + updateFanSpeed(pwmMinimumValue + pwmStep*pwmStepSize); + } - if ((temp == NAN) || (temp <= -100.0)) { + uint8_t calculatePwmStep(float diffTemp){ + if ((diffTemp == NAN) || (diffTemp <= -100.0)) { DEBUG_PRINTLN(F("WARNING: no temperature value available. Cannot do temperature control. Will set PWM fan to 255.")); - } else if (difftemp <= 0.0) { - // Temperature is below target temperature. Run fan at minimum speed. - newPWMvalue = pwmMinimumValue; - } else if (difftemp <= 0.5) { - newPWMvalue = pwmMinimumValue + pwmStep; - } else if (difftemp <= 1.0) { - newPWMvalue = pwmMinimumValue + 2*pwmStep; - } else if (difftemp <= 1.5) { - newPWMvalue = pwmMinimumValue + 3*pwmStep; - } else if (difftemp <= 2.0) { - newPWMvalue = pwmMinimumValue + 4*pwmStep; - } else if (difftemp <= 2.5) { - newPWMvalue = pwmMinimumValue + 5*pwmStep; - } else if (difftemp <= 3.0) { - newPWMvalue = pwmMinimumValue + 6*pwmStep; - } else { - newPWMvalue = pwmMinimumValue + 7*pwmStep; + return _pwmMaxStepCount; } - updateFanSpeed(newPWMvalue); + if(diffTemp <=0){ + return 0; + } + int calculatedStep = (diffTemp / _pwmTempStepSize)+1; + // anything greater than max stepcount gets max + return (uint8_t)min((int)_pwmMaxStepCount,calculatedStep); } public: