From 151201656f9dcbf3ef96a3d921ff8deca39878a8 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Tue, 15 May 2018 21:14:10 -0500
Subject: [PATCH] Add FAN_MAX_PWM for M106-controlled fans

---
 Marlin/Conditionals_post.h | 17 +++++++++++++++++
 Marlin/Configuration_adv.h | 16 +++++++++++++---
 Marlin/planner.cpp         |  4 ++--
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index 54d22278f6..26c255ce8c 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -880,6 +880,23 @@
    */
   #define HAS_FANMUX PIN_EXISTS(FANMUX0)
 
+  /**
+   * MIN/MAX fan PWM scaling
+   */
+  #ifndef FAN_MIN_PWM
+    #define FAN_MIN_PWM 0
+  #endif
+  #ifndef FAN_MAX_PWM
+    #define FAN_MAX_PWM 255
+  #endif
+  #if FAN_MIN_PWM < 0 || FAN_MIN_PWM > 255
+    #error "FAN_MIN_PWM must be a value from 0 to 255."
+  #elif FAN_MAX_PWM < 0 || FAN_MAX_PWM > 255
+    #error "FAN_MAX_PWM must be a value from 0 to 255."
+  #elif FAN_MIN_PWM > FAN_MAX_PWM
+    #error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM."
+  #endif
+
   /**
    * Bed Probe dependencies
    */
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 0decaf8871..9cfbc8957c 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -208,10 +208,20 @@
 // before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
 //#define FAN_KICKSTART_TIME 100
 
-// This defines the minimal speed for the main fan, run in PWM mode
-// to enable uncomment and set minimal PWM speed for reliable running (1-255)
-// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM
+/**
+ * PWM Fan Scaling
+ *
+ * Define the min/max speeds for PWM fans (as set with M106).
+ *
+ * With these options the M106 0-255 value range is scaled to a subset
+ * to ensure that the fan has enough power to spin, or to run lower
+ * current fans with higher current. (e.g., 5V/12V fans with 12V/24V)
+ * Value 0 always turns off the fan.
+ *
+ * Define one or both of these to override the default 0-255 range.
+ */
 //#define FAN_MIN_PWM 50
+//#define FAN_MAX_PWM 128
 
 // @section extruder
 
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index f504665f0d..4d4b92e9dc 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -1084,8 +1084,8 @@ void Planner::check_axes_activity() {
 
     #endif // FAN_KICKSTART_TIME > 0
 
-    #ifdef FAN_MIN_PWM
-      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0)
+    #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
+      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? map(tail_fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : 0)
     #else
       #define CALC_FAN_SPEED(f) tail_fan_speed[f]
     #endif
-- 
GitLab