diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index b0a06195cd..1966f436fe 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -505,6 +505,12 @@
     #define BED_USES_THERMISTOR
   #endif
 
+  /**
+   * Flags for PID handling
+   */
+  #define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED))
+  #define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED))
+
   /**
    * ARRAY_BY_EXTRUDERS based on EXTRUDERS
    */
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 7b232e56bd..dabd765321 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -5559,7 +5559,7 @@ inline void gcode_M226() {
  *       U<bool> with a non-zero value will apply the result to current settings
  */
 inline void gcode_M303() {
-  #if ENABLED(PIDTEMP)
+  #if HAS_PID_HEATING
     int e = code_seen('E') ? code_value_short() : 0;
     int c = code_seen('C') ? code_value_short() : 5;
     bool u = code_seen('U') && code_value_short() != 0;
diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp
index 7d5a1b4d67..ced96e2602 100644
--- a/Marlin/configuration_store.cpp
+++ b/Marlin/configuration_store.cpp
@@ -794,7 +794,7 @@ void Config_PrintSettings(bool forReplay) {
     SERIAL_EOL;
   #endif // ULTIPANEL
 
-  #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
+  #if HAS_PID_HEATING
 
     CONFIG_ECHO_START;
     if (!forReplay) {
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index bfbadc6cbe..cb175efc8f 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -221,7 +221,7 @@ static void updateTemperaturesFromRawValues();
 //================================ Functions ================================
 //===========================================================================
 
-#if ENABLED(PIDTEMP)
+#if HAS_PID_HEATING
 
   void PID_autotune(float temp, int extruder, int ncycles, bool set_result/*=false*/) {
     float input = 0.0;
@@ -240,8 +240,13 @@ static void updateTemperaturesFromRawValues();
       millis_t next_auto_fan_check_ms = temp_ms + 2500UL;
     #endif
 
-    if (extruder >= EXTRUDERS
-      #if !HAS_TEMP_BED
+    if (false
+      #if ENABLED(PIDTEMP)
+         || extruder >= EXTRUDERS
+      #else
+         || extruder >= 0
+      #endif
+      #if DISABLED(PIDTEMPBED)
          || extruder < 0
       #endif
     ) {
@@ -253,10 +258,16 @@ static void updateTemperaturesFromRawValues();
 
     disable_all_heaters(); // switch off all heaters.
 
-    if (extruder < 0)
-      soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
-    else
+    #if HAS_PID_FOR_BOTH
+      if (extruder < 0)
+        soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
+      else
+        soft_pwm[extruder] = bias = d = (PID_MAX) / 2;
+    #elif ENABLED(PIDTEMP)
       soft_pwm[extruder] = bias = d = (PID_MAX) / 2;
+    #else
+      soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
+    #endif
 
     // PID Tuning loop
     for (;;) {
@@ -266,7 +277,15 @@ static void updateTemperaturesFromRawValues();
       if (temp_meas_ready) { // temp sample ready
         updateTemperaturesFromRawValues();
 
-        input = (extruder < 0) ? current_temperature_bed : current_temperature[extruder];
+        input =
+          #if HAS_PID_FOR_BOTH
+            extruder < 0 ? current_temperature_bed : current_temperature[extruder]
+          #elif ENABLED(PIDTEMP)
+            current_temperature[extruder]
+          #else
+            current_temperature_bed
+          #endif
+        ;
 
         max = max(max, input);
         min = min(min, input);
@@ -281,10 +300,16 @@ static void updateTemperaturesFromRawValues();
         if (heating && input > temp) {
           if (ELAPSED(ms, t2 + 5000UL)) {
             heating = false;
-            if (extruder < 0)
-              soft_pwm_bed = (bias - d) >> 1;
-            else
+            #if HAS_PID_FOR_BOTH
+              if (extruder < 0)
+                soft_pwm_bed = (bias - d) >> 1;
+              else
+                soft_pwm[extruder] = (bias - d) >> 1;
+            #elif ENABLED(PIDTEMP)
               soft_pwm[extruder] = (bias - d) >> 1;
+            #elif ENABLED(PIDTEMPBED)
+              soft_pwm_bed = (bias - d) >> 1;
+            #endif
             t1 = ms;
             t_high = t1 - t2;
             max = temp;
@@ -297,7 +322,15 @@ static void updateTemperaturesFromRawValues();
             t2 = ms;
             t_low = t2 - t1;
             if (cycles > 0) {
-              long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX;
+              long max_pow =
+                #if HAS_PID_FOR_BOTH
+                  extruder < 0 ? MAX_BED_POWER : PID_MAX
+                #elif ENABLED(PIDTEMP)
+                  PID_MAX
+                #else
+                  MAX_BED_POWER
+                #endif
+              ;
               bias += (d * (t_high - t_low)) / (t_low + t_high);
               bias = constrain(bias, 20, max_pow - 20);
               d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
@@ -336,10 +369,16 @@ static void updateTemperaturesFromRawValues();
                 */
               }
             }
-            if (extruder < 0)
-              soft_pwm_bed = (bias + d) >> 1;
-            else
+            #if HAS_PID_FOR_BOTH
+              if (extruder < 0)
+                soft_pwm_bed = (bias + d) >> 1;
+              else
+                soft_pwm[extruder] = (bias + d) >> 1;
+            #elif ENABLED(PIDTEMP)
               soft_pwm[extruder] = (bias + d) >> 1;
+            #else
+              soft_pwm_bed = (bias + d) >> 1;
+            #endif
             cycles++;
             min = temp;
           }
@@ -366,27 +405,48 @@ static void updateTemperaturesFromRawValues();
       }
       if (cycles > ncycles) {
         SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
-        const char* estring = extruder < 0 ? "bed" : "";
-        SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kp "); SERIAL_PROTOCOLLN(workKp);
-        SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Ki "); SERIAL_PROTOCOLLN(workKi);
-        SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kd "); SERIAL_PROTOCOLLN(workKd);
+
+        #if HAS_PID_FOR_BOTH
+          const char* estring = extruder < 0 ? "bed" : "";
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kp "); SERIAL_PROTOCOLLN(workKp);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Ki "); SERIAL_PROTOCOLLN(workKi);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kd "); SERIAL_PROTOCOLLN(workKd);
+        #elif ENABLED(PIDTEMP)
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_Kp "); SERIAL_PROTOCOLLN(workKp);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_Ki "); SERIAL_PROTOCOLLN(workKi);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_Kd "); SERIAL_PROTOCOLLN(workKd);
+        #else
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_bedKp "); SERIAL_PROTOCOLLN(workKp);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_bedKi "); SERIAL_PROTOCOLLN(workKi);
+          SERIAL_PROTOCOLPGM("#define  DEFAULT_bedKd "); SERIAL_PROTOCOLLN(workKd);
+        #endif
+
+        #define _SET_BED_PID() \
+          bedKp = workKp; \
+          bedKi = scalePID_i(workKi); \
+          bedKd = scalePID_d(workKd); \
+          updatePID()
+
+        #define _SET_EXTRUDER_PID() \
+          PID_PARAM(Kp, extruder) = workKp; \
+          PID_PARAM(Ki, extruder) = scalePID_i(workKi); \
+          PID_PARAM(Kd, extruder) = scalePID_d(workKd); \
+          updatePID()
 
         // Use the result? (As with "M303 U1")
         if (set_result) {
-          if (extruder < 0) {
-            #if ENABLED(PIDTEMPBED)
-              bedKp = workKp;
-              bedKi = scalePID_i(workKi);
-              bedKd = scalePID_d(workKd);
-              updatePID();
-            #endif
-          }
-          else {
-            PID_PARAM(Kp, extruder) = workKp;
-            PID_PARAM(Ki, extruder) = scalePID_i(workKi);
-            PID_PARAM(Kd, extruder) = scalePID_d(workKd);
-            updatePID();
-          }
+          #if HAS_PID_FOR_BOTH
+            if (extruder < 0) {
+              _SET_BED_PID();
+            }
+            else {
+              _SET_EXTRUDER_PID();
+            }
+          #elif ENABLED(PIDTEMP)
+            _SET_EXTRUDER_PID();
+          #else
+            _SET_BED_PID();
+          #endif
         }
         return;
       }
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index a8296c0db6..cb9e717fbc 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1343,7 +1343,7 @@ static void lcd_control_menu() {
   static void _lcd_autotune(int e) {
     char cmd[30];
     sprintf_P(cmd, PSTR("M303 U1 E%d S%d"), e,
-      #if ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED)
+      #if HAS_PID_FOR_BOTH
         e < 0 ? autotune_temp_bed : autotune_temp[e]
       #elif ENABLED(PIDTEMPBED)
         autotune_temp_bed