diff --git a/Marlin/src/gcode/temperature/M303.cpp b/Marlin/src/gcode/temperature/M303.cpp
index afd373bf62..2765dc64b4 100644
--- a/Marlin/src/gcode/temperature/M303.cpp
+++ b/Marlin/src/gcode/temperature/M303.cpp
@@ -36,19 +36,18 @@
  *       U<bool> with a non-zero value will apply the result to current settings
  */
 void GcodeSuite::M303() {
-
-  const int8_t e = parser.intval('E');
-
-  if (!WITHIN(e, 0
-    #if ENABLED(PIDTEMPBED)
-      -1
-    #endif
-    ,
-    #if ENABLED(PIDTEMP)
-      HOTENDS
-    #endif
-    -1
-  )) {
+  #if ENABLED(PIDTEMPBED)
+    #define SI H_BED
+  #else
+    #define SI H_E0
+  #endif
+  #if ENABLED(PIDTEMP)
+    #define EI HOTENDS - 1
+  #else
+    #define EI H_BED
+  #endif
+  const heater_ind_t e = (heater_ind_t)parser.intval('E');
+  if (!WITHIN(e, SI, EI)) {
     SERIAL_ECHOLNPGM(MSG_PID_BAD_EXTRUDER_NUM);
     return;
   }
diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp
index 9856dc0f34..0a3825f88b 100644
--- a/Marlin/src/module/temperature.cpp
+++ b/Marlin/src/module/temperature.cpp
@@ -94,12 +94,12 @@ Temperature thermalManager;
  */
 
 #if HAS_HEATED_BED
-  #define _BED_PSTR(M,E) (E) == -1 ? PSTR(M) :
+  #define _BED_PSTR(M,E) (E) == H_BED ? PSTR(M) :
 #else
   #define _BED_PSTR(M,E)
 #endif
 #if HAS_HEATED_CHAMBER
-  #define _CHAMBER_PSTR(M,E) (E) == -2 ? PSTR(M) :
+  #define _CHAMBER_PSTR(M,E) (E) == H_CHAMBER ? PSTR(M) :
 #else
   #define _CHAMBER_PSTR(M,E)
 #endif
@@ -345,7 +345,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
    * Needs sufficient heater power to make some overshoot at target
    * temperature to succeed.
    */
-  void Temperature::PID_autotune(const float &target, const int8_t heater, const int8_t ncycles, const bool set_result/*=false*/) {
+  void Temperature::PID_autotune(const float &target, const heater_ind_t heater, const int8_t ncycles, const bool set_result/*=false*/) {
     float current = 0.0;
     int cycles = 0;
     bool heating = true;
@@ -357,7 +357,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
     PID_t tune_pid = { 0, 0, 0 };
     float max = 0, min = 10000;
 
-    const bool isbed = (heater < 0);
+    const bool isbed = (heater == H_BED);
 
     #if HAS_PID_FOR_BOTH
       #define GHV(B,H) (isbed ? (B) : (H))
@@ -618,26 +618,16 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
 
 Temperature::Temperature() { }
 
-int16_t Temperature::getHeaterPower(const int8_t heater) {
-  return (
-    #if HAS_HEATED_CHAMBER
-      #if HAS_HEATED_BED
-        heater == -2
-      #else
-        heater < 0
-      #endif
-      ? temp_chamber.soft_pwm_amount :
-    #endif
+int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) {
+  switch (heater_id) {
+    default: return temp_hotend[heater_id].soft_pwm_amount;
     #if HAS_HEATED_BED
-      #if HAS_HEATED_CHAMBER
-        heater == -1
-      #else
-        heater < 0
-      #endif
-      ? temp_bed.soft_pwm_amount :
+      case H_BED: return temp_bed.soft_pwm_amount;
     #endif
-    temp_hotend[heater].soft_pwm_amount
-  );
+    #if HAS_HEATED_CHAMBER
+      case H_CHAMBER: return temp_chamber.soft_pwm_amount;
+    #endif
+  }
 }
 
 #if HAS_AUTO_FAN
@@ -756,7 +746,7 @@ int16_t Temperature::getHeaterPower(const int8_t heater) {
 //
 // Temperature Error Handlers
 //
-void Temperature::_temp_error(const int8_t heater, PGM_P const serial_msg, PGM_P const lcd_msg) {
+void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, PGM_P const lcd_msg) {
   static bool killed = false;
   if (IsRunning()) {
     SERIAL_ERROR_START();
@@ -764,7 +754,7 @@ void Temperature::_temp_error(const int8_t heater, PGM_P const serial_msg, PGM_P
     SERIAL_ECHOPGM(MSG_STOPPED_HEATER);
     if (heater >= 0) SERIAL_ECHO((int)heater);
     #if HAS_HEATED_CHAMBER
-      else if (heater == -2) SERIAL_ECHOPGM(MSG_HEATER_CHAMBER);
+      else if (heater == H_CHAMBER) SERIAL_ECHOPGM(MSG_HEATER_CHAMBER);
     #endif
     else SERIAL_ECHOPGM(MSG_HEATER_BED);
     SERIAL_EOL();
@@ -794,21 +784,22 @@ void Temperature::_temp_error(const int8_t heater, PGM_P const serial_msg, PGM_P
   #endif
 }
 
-void Temperature::max_temp_error(const int8_t heater) {
+void Temperature::max_temp_error(const heater_ind_t heater) {
   _temp_error(heater, PSTR(MSG_T_MAXTEMP), TEMP_ERR_PSTR(MSG_ERR_MAXTEMP, heater));
 }
 
-void Temperature::min_temp_error(const int8_t heater) {
+void Temperature::min_temp_error(const heater_ind_t heater) {
   _temp_error(heater, PSTR(MSG_T_MINTEMP), TEMP_ERR_PSTR(MSG_ERR_MINTEMP, heater));
 }
 
-float Temperature::get_pid_output(const int8_t e) {
+float Temperature::get_pid_output_hotend(const uint8_t e) {
   #if HOTENDS == 1
     #define _HOTEND_TEST true
   #else
     #define _HOTEND_TEST (e == active_extruder)
   #endif
   E_UNUSED();
+  const uint8_t ee = HOTEND_INDEX;
   float pid_output;
   #if ENABLED(PIDTEMP)
     #if DISABLED(PID_OPENLOOP)
@@ -816,38 +807,38 @@ float Temperature::get_pid_output(const int8_t e) {
       static float temp_iState[HOTENDS] = { 0 },
                    temp_dState[HOTENDS] = { 0 };
       static bool pid_reset[HOTENDS] = { false };
-      const float pid_error = temp_hotend[HOTEND_INDEX].target - temp_hotend[HOTEND_INDEX].current;
+      const float pid_error = temp_hotend[ee].target - temp_hotend[ee].current;
 
-      if (temp_hotend[HOTEND_INDEX].target == 0
+      if (temp_hotend[ee].target == 0
         || pid_error < -(PID_FUNCTIONAL_RANGE)
         #if HEATER_IDLE_HANDLER
-          || hotend_idle[HOTEND_INDEX].timed_out
+          || hotend_idle[ee].timed_out
         #endif
       ) {
         pid_output = 0;
-        pid_reset[HOTEND_INDEX] = true;
+        pid_reset[ee] = true;
       }
       else if (pid_error > PID_FUNCTIONAL_RANGE) {
         pid_output = BANG_MAX;
-        pid_reset[HOTEND_INDEX] = true;
+        pid_reset[ee] = true;
       }
       else {
-        if (pid_reset[HOTEND_INDEX]) {
-          temp_iState[HOTEND_INDEX] = 0.0;
-          work_pid[HOTEND_INDEX].Kd = 0.0;
-          pid_reset[HOTEND_INDEX] = false;
+        if (pid_reset[ee]) {
+          temp_iState[ee] = 0.0;
+          work_pid[ee].Kd = 0.0;
+          pid_reset[ee] = false;
         }
 
-        work_pid[HOTEND_INDEX].Kd = work_pid[HOTEND_INDEX].Kd + PID_K2 * (PID_PARAM(Kd, HOTEND_INDEX) * (temp_dState[HOTEND_INDEX] - temp_hotend[HOTEND_INDEX].current) - work_pid[HOTEND_INDEX].Kd);
-        const float max_power_over_i_gain = (float)PID_MAX / PID_PARAM(Ki, HOTEND_INDEX);
-        temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX] + pid_error, 0, max_power_over_i_gain);
-        work_pid[HOTEND_INDEX].Kp = PID_PARAM(Kp, HOTEND_INDEX) * pid_error;
-        work_pid[HOTEND_INDEX].Ki = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
+        work_pid[ee].Kd = work_pid[ee].Kd + PID_K2 * (PID_PARAM(Kd, ee) * (temp_dState[ee] - temp_hotend[ee].current) - work_pid[ee].Kd);
+        const float max_power_over_i_gain = (float)PID_MAX / PID_PARAM(Ki, ee);
+        temp_iState[ee] = constrain(temp_iState[ee] + pid_error, 0, max_power_over_i_gain);
+        work_pid[ee].Kp = PID_PARAM(Kp, ee) * pid_error;
+        work_pid[ee].Ki = PID_PARAM(Ki, ee) * temp_iState[ee];
 
-        pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki + work_pid[HOTEND_INDEX].Kd;
+        pid_output = work_pid[ee].Kp + work_pid[ee].Ki + work_pid[ee].Kd;
 
         #if ENABLED(PID_EXTRUSION_SCALING)
-          work_pid[HOTEND_INDEX].Kc = 0;
+          work_pid[ee].Kc = 0;
           if (_HOTEND_TEST) {
             const long e_position = stepper.position(E_AXIS);
             if (e_position > last_e_position) {
@@ -858,49 +849,51 @@ float Temperature::get_pid_output(const int8_t e) {
               lpq[lpq_ptr] = 0;
 
             if (++lpq_ptr >= lpq_len) lpq_ptr = 0;
-            work_pid[HOTEND_INDEX].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX);
-            pid_output += work_pid[HOTEND_INDEX].Kc;
+            work_pid[ee].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, ee);
+            pid_output += work_pid[ee].Kc;
           }
         #endif // PID_EXTRUSION_SCALING
 
         pid_output = constrain(pid_output, 0, PID_MAX);
       }
-      temp_dState[HOTEND_INDEX] = temp_hotend[HOTEND_INDEX].current;
+      temp_dState[ee] = temp_hotend[ee].current;
 
     #else // PID_OPENLOOP
 
-      const float pid_output = constrain(temp_hotend[HOTEND_INDEX].target, 0, PID_MAX);
+      const float pid_output = constrain(temp_hotend[ee].target, 0, PID_MAX);
 
     #endif // PID_OPENLOOP
 
     #if ENABLED(PID_DEBUG)
       SERIAL_ECHO_START();
       SERIAL_ECHOPAIR(
-        MSG_PID_DEBUG, HOTEND_INDEX,
-        MSG_PID_DEBUG_INPUT, temp_hotend[HOTEND_INDEX].current,
+        MSG_PID_DEBUG, ee,
+        MSG_PID_DEBUG_INPUT, temp_hotend[ee].current,
         MSG_PID_DEBUG_OUTPUT, pid_output
       );
       #if DISABLED(PID_OPENLOOP)
         SERIAL_ECHOPAIR(
-          MSG_PID_DEBUG_PTERM, work_pid[HOTEND_INDEX].Kp,
-          MSG_PID_DEBUG_ITERM, work_pid[HOTEND_INDEX].Ki,
-          MSG_PID_DEBUG_DTERM, work_pid[HOTEND_INDEX].Kd
+          MSG_PID_DEBUG_PTERM, work_pid[ee].Kp,
+          MSG_PID_DEBUG_ITERM, work_pid[ee].Ki,
+          MSG_PID_DEBUG_DTERM, work_pid[ee].Kd
           #if ENABLED(PID_EXTRUSION_SCALING)
-            , MSG_PID_DEBUG_CTERM, work_pid[HOTEND_INDEX].Kc
+            , MSG_PID_DEBUG_CTERM, work_pid[ee].Kc
           #endif
         );
       #endif
       SERIAL_EOL();
     #endif // PID_DEBUG
 
-  #else /* PID off */
+  #else // No PID enabled
+
     #if HEATER_IDLE_HANDLER
-      #define _TIMED_OUT_TEST hotend_idle[HOTEND_INDEX].timed_out
+      #define _TIMED_OUT_TEST hotend_idle[ee].timed_out
     #else
       #define _TIMED_OUT_TEST false
     #endif
-    pid_output = (!_TIMED_OUT_TEST && temp_hotend[HOTEND_INDEX].current < temp_hotend[HOTEND_INDEX].target) ? BANG_MAX : 0;
+    pid_output = (!_TIMED_OUT_TEST && temp_hotend[ee].current < temp_hotend[ee].target) ? BANG_MAX : 0;
     #undef _TIMED_OUT_TEST
+
   #endif
 
   return pid_output;
@@ -983,13 +976,13 @@ void Temperature::manage_heater() {
   updateTemperaturesFromRawValues(); // also resets the watchdog
 
   #if ENABLED(HEATER_0_USES_MAX6675)
-    if (temp_hotend[0].current > MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(0);
-    if (temp_hotend[0].current < MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(0);
+    if (temp_hotend[0].current > MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(H_E0);
+    if (temp_hotend[0].current < MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(H_E0);
   #endif
 
   #if ENABLED(HEATER_1_USES_MAX6675)
-    if (temp_hotend[1].current > MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(1);
-    if (temp_hotend[1].current < MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(1);
+    if (temp_hotend[1].current > MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(H_E1);
+    if (temp_hotend[1].current < MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(H_E1);
   #endif
 
   #define HAS_THERMAL_PROTECTION (ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED || ENABLED(THERMAL_PROTECTION_CHAMBER))
@@ -1010,7 +1003,7 @@ void Temperature::manage_heater() {
   HOTEND_LOOP() {
     #if ENABLED(THERMAL_PROTECTION_HOTENDS)
       if (!grace_period && degHotend(e) > temp_range[e].maxtemp)
-        _temp_error(e, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, e));
+        _temp_error((heater_ind_t)e, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, e));
     #endif
 
     #if HEATER_IDLE_HANDLER
@@ -1019,25 +1012,25 @@ void Temperature::manage_heater() {
 
     #if ENABLED(THERMAL_PROTECTION_HOTENDS)
       // Check for thermal runaway
-      thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].current, temp_hotend[e].target, e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
+      thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].current, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
     #endif
 
-    temp_hotend[e].soft_pwm_amount = (temp_hotend[e].current > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].current < temp_range[e].maxtemp ? (int)get_pid_output(e) >> 1 : 0;
+    temp_hotend[e].soft_pwm_amount = (temp_hotend[e].current > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].current < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0;
 
     #if WATCH_HOTENDS
       // Make sure temperature is increasing
       if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder?
         if (degHotend(e) < watch_hotend[e].target)                             // Failed to increase enough?
-          _temp_error(e, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, e));
+          _temp_error((heater_ind_t)e, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, e));
         else                                                                 // Start again if the target is still far off
-          start_watching_heater(e);
+          start_watching_hotend(e);
       }
     #endif
 
     #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
       // Make sure measured temperatures are close together
       if (ABS(temp_hotend[0].current - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF)
-        _temp_error(0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP));
+        _temp_error(H_E0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP));
     #endif
 
   } // HOTEND_LOOP
@@ -1066,14 +1059,14 @@ void Temperature::manage_heater() {
 
     #if ENABLED(THERMAL_PROTECTION_BED)
       if (!grace_period && degBed() > BED_MAXTEMP)
-        _temp_error(-1, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, -1));
+        _temp_error(H_BED, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, H_BED));
     #endif
 
     #if WATCH_BED
       // Make sure temperature is increasing
       if (watch_bed.elapsed(ms)) {        // Time to check the bed?
         if (degBed() < watch_bed.target)                                // Failed to increase enough?
-          _temp_error(-1, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, -1));
+          _temp_error(H_BED, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, H_BED));
         else                                                            // Start again if the target is still far off
           start_watching_bed();
       }
@@ -1098,7 +1091,7 @@ void Temperature::manage_heater() {
       #endif
 
       #if HAS_THERMALLY_PROTECTED_BED
-        thermal_runaway_protection(tr_state_machine_bed, temp_bed.current, temp_bed.target, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
+        thermal_runaway_protection(tr_state_machine_bed, temp_bed.current, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
       #endif
 
       #if HEATER_IDLE_HANDLER
@@ -1144,14 +1137,14 @@ void Temperature::manage_heater() {
 
     #if ENABLED(THERMAL_PROTECTION_CHAMBER)
       if (!grace_period && degChamber() > CHAMBER_MAXTEMP)
-        _temp_error(-2, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, -2));
+        _temp_error(H_CHAMBER, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, H_CHAMBER));
     #endif
 
     #if WATCH_CHAMBER
       // Make sure temperature is increasing
       if (watch_chamber.elapsed(ms)) {              // Time to check the chamber?
         if (degChamber() < watch_chamber.target)    // Failed to increase enough?
-          _temp_error(-2, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, -2));
+          _temp_error(H_CHAMBER, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, H_CHAMBER));
         else
           start_watching_chamber();                 // Start again if the target is still far off
       }
@@ -1176,7 +1169,7 @@ void Temperature::manage_heater() {
       }
 
       #if ENABLED(THERMAL_PROTECTION_CHAMBER)
-        thermal_runaway_protection(tr_state_machine_chamber, temp_chamber.current, temp_chamber.target, -2, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS);
+        thermal_runaway_protection(tr_state_machine_chamber, temp_chamber.current, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS);
       #endif
     }
 
@@ -1782,14 +1775,15 @@ void Temperature::init() {
    * their target temperature by a configurable margin.
    * This is called when the temperature is set. (M104, M109)
    */
-  void Temperature::start_watching_heater(const uint8_t e) {
+  void Temperature::start_watching_hotend(const uint8_t e) {
     E_UNUSED();
-    if (degTargetHotend(HOTEND_INDEX) && degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
-      watch_hotend[HOTEND_INDEX].target = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE;
-      watch_hotend[HOTEND_INDEX].next_ms = millis() + (WATCH_TEMP_PERIOD) * 1000UL;
+    const uint8_t ee = HOTEND_INDEX;
+    if (degTargetHotend(ee) && degHotend(ee) < degTargetHotend(ee) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
+      watch_hotend[ee].target = degHotend(ee) + WATCH_TEMP_INCREASE;
+      watch_hotend[ee].next_ms = millis() + (WATCH_TEMP_PERIOD) * 1000UL;
     }
     else
-      watch_hotend[HOTEND_INDEX].next_ms = 0;
+      watch_hotend[ee].next_ms = 0;
   }
 #endif
 
@@ -1837,14 +1831,14 @@ void Temperature::init() {
     Temperature::tr_state_machine_t Temperature::tr_state_machine_chamber; // = { TRInactive, 0 };
   #endif
 
-  void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float &current, const float &target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) {
+  void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float &current, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) {
 
     static float tr_target_temperature[HOTENDS + 1] = { 0.0 };
 
     /**
       SERIAL_ECHO_START();
       SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: ");
-      if (heater_id == -2) SERIAL_ECHOPGM("chamber");
+      if (heater_id == H_CHAMBER) SERIAL_ECHOPGM("chamber");
       if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id);
       SERIAL_ECHOPAIR(" ;  State:", sm.state, " ;  Timer:", sm.timer, " ;  Temperature:", current, " ;  Target Temp:", target);
       if (heater_id >= 0)
@@ -2233,12 +2227,12 @@ void Temperature::readings_ready() {
           || temp_hotend[e].soft_pwm_amount > 0
         #endif
       );
-      if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error(e);
+      if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e);
       if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) {
         #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
           if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
         #endif
-          min_temp_error(e);
+          min_temp_error((heater_ind_t)e);
       }
       #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
         else
@@ -2258,8 +2252,8 @@ void Temperature::readings_ready() {
         || (temp_bed.soft_pwm_amount > 0)
       #endif
     ;
-    if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(-1);
-    if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(-1);
+    if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED);
+    if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED);
   #endif
 
   #if HAS_HEATED_CHAMBER
@@ -2269,8 +2263,8 @@ void Temperature::readings_ready() {
       #define CHAMBERCMP(A,B) ((A)>=(B))
     #endif
     const bool chamber_on = (temp_chamber.target > 0);
-    if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(-2);
-    if (chamber_on && CHAMBERCMP(mintemp_raw_CHAMBER, temp_chamber.raw)) min_temp_error(-2);
+    if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(H_CHAMBER);
+    if (chamber_on && CHAMBERCMP(mintemp_raw_CHAMBER, temp_chamber.raw)) min_temp_error(H_CHAMBER);
   #endif
 }
 
@@ -2782,20 +2776,20 @@ void Temperature::isr() {
     #if ENABLED(SHOW_TEMP_ADC_VALUES)
       , const float r
     #endif
-    , const int8_t e=-3
+    , const heater_ind_t e=INDEX_NONE
   ) {
     char k;
     switch (e) {
       #if HAS_TEMP_CHAMBER
-        case -2: k = 'C'; break;
+        case H_CHAMBER: k = 'C'; break;
       #endif
       #if HAS_TEMP_HOTEND
         default: k = 'T'; break;
         #if HAS_HEATED_BED
-          case -1: k = 'B'; break;
+          case H_BED: k = 'B'; break;
         #endif
         #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
-          case -3: k = 'R'; break;
+          case H_REDUNDANT: k = 'R'; break;
         #endif
       #elif HAS_HEATED_BED
         default: k = 'B'; break;
@@ -2832,7 +2826,7 @@ void Temperature::isr() {
           #if ENABLED(SHOW_TEMP_ADC_VALUES)
             , redundant_temperature_raw
           #endif
-          , -3 // REDUNDANT
+          , H_REDUNDANT
         );
       #endif
     #endif
@@ -2841,7 +2835,7 @@ void Temperature::isr() {
         #if ENABLED(SHOW_TEMP_ADC_VALUES)
           , rawBedTemp()
         #endif
-        , -1 // BED
+        , H_BED
       );
     #endif
     #if HAS_TEMP_CHAMBER
@@ -2854,7 +2848,7 @@ void Temperature::isr() {
         #if ENABLED(SHOW_TEMP_ADC_VALUES)
           , rawChamberTemp()
         #endif
-        , -2 // CHAMBER
+        , H_CHAMBER
       );
     #endif // HAS_TEMP_CHAMBER
     #if HOTENDS > 1
@@ -2862,21 +2856,21 @@ void Temperature::isr() {
         #if ENABLED(SHOW_TEMP_ADC_VALUES)
           , rawHotendTemp(e)
         #endif
-        , e
+        , (heater_ind_t)e
       );
     #endif
-    SERIAL_ECHOPAIR(" @:", getHeaterPower(target_extruder));
+    SERIAL_ECHOPAIR(" @:", getHeaterPower((heater_ind_t)target_extruder));
     #if HAS_HEATED_BED
-      SERIAL_ECHOPAIR(" B@:", getHeaterPower(-1));
+      SERIAL_ECHOPAIR(" B@:", getHeaterPower(H_BED));
     #endif
     #if HAS_HEATED_CHAMBER
-      SERIAL_ECHOPAIR(" C@:", getHeaterPower(-2));
+      SERIAL_ECHOPAIR(" C@:", getHeaterPower(H_CHAMBER));
     #endif
     #if HOTENDS > 1
       HOTEND_LOOP() {
         SERIAL_ECHOPAIR(" @", e);
         SERIAL_CHAR(':');
-        SERIAL_ECHO(getHeaterPower(e));
+        SERIAL_ECHO(getHeaterPower((heater_ind_t)e));
       }
     #endif
   }
diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h
index a4499ad0fa..3ea172fe97 100644
--- a/Marlin/src/module/temperature.h
+++ b/Marlin/src/module/temperature.h
@@ -45,6 +45,13 @@
   #define E_UNUSED()
 #endif
 
+// Identifiers for other heaters
+typedef enum : int8_t {
+  INDEX_NONE = -4,
+  H_REDUNDANT, H_CHAMBER, H_BED,
+  H_E0, H_E1, H_E2, H_E3, H_E4, H_E5
+} heater_ind_t;
+
 // PID storage
 typedef struct { float Kp, Ki, Kd;     } PID_t;
 typedef struct { float Kp, Ki, Kd, Kc; } PIDC_t;
@@ -580,33 +587,34 @@ class Temperature {
     }
 
     #if WATCH_HOTENDS
-      static void start_watching_heater(const uint8_t e=0);
+      static void start_watching_hotend(const uint8_t e=0);
     #else
-      static inline void start_watching_heater(const uint8_t e=0) { UNUSED(e); }
+      static inline void start_watching_hotend(const uint8_t e=0) { UNUSED(e); }
     #endif
 
     #if HAS_LCD_MENU
-      static inline void start_watching_E0() { start_watching_heater(0); }
-      static inline void start_watching_E1() { start_watching_heater(1); }
-      static inline void start_watching_E2() { start_watching_heater(2); }
-      static inline void start_watching_E3() { start_watching_heater(3); }
-      static inline void start_watching_E4() { start_watching_heater(4); }
-      static inline void start_watching_E5() { start_watching_heater(5); }
+      static inline void start_watching_E0() { start_watching_hotend(0); }
+      static inline void start_watching_E1() { start_watching_hotend(1); }
+      static inline void start_watching_E2() { start_watching_hotend(2); }
+      static inline void start_watching_E3() { start_watching_hotend(3); }
+      static inline void start_watching_E4() { start_watching_hotend(4); }
+      static inline void start_watching_E5() { start_watching_hotend(5); }
     #endif
 
     static void setTargetHotend(const int16_t celsius, const uint8_t e) {
       E_UNUSED();
+      const uint8_t ee = HOTEND_INDEX;
       #ifdef MILLISECONDS_PREHEAT_TIME
         if (celsius == 0)
-          reset_preheat_time(HOTEND_INDEX);
-        else if (temp_hotend[HOTEND_INDEX].target == 0)
-          start_preheat_time(HOTEND_INDEX);
+          reset_preheat_time(ee);
+        else if (temp_hotend[ee].target == 0)
+          start_preheat_time(ee);
       #endif
       #if ENABLED(AUTO_POWER_CONTROL)
         powerManager.power_on();
       #endif
-      temp_hotend[HOTEND_INDEX].target = MIN(celsius, temp_range[HOTEND_INDEX].maxtemp - 15);
-      start_watching_heater(HOTEND_INDEX);
+      temp_hotend[ee].target = MIN(celsius, temp_range[ee].maxtemp - 15);
+      start_watching_hotend(ee);
     }
 
     #if WATCH_CHAMBER
@@ -705,7 +713,7 @@ class Temperature {
     /**
      * The software PWM power for a heater
      */
-    static int16_t getHeaterPower(const int8_t heater);
+    static int16_t getHeaterPower(const heater_ind_t heater);
 
     /**
      * Switch off all heaters, set all target temperatures to 0
@@ -716,7 +724,7 @@ class Temperature {
      * Perform auto-tuning for hotend or bed in response to M303
      */
     #if HAS_PID_HEATING
-      static void PID_autotune(const float &target, const int8_t hotend, const int8_t ncycles, const bool set_result=false);
+      static void PID_autotune(const float &target, const heater_ind_t hotend, const int8_t ncycles, const bool set_result=false);
 
       #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING)
         static bool adaptive_fan_slowing;
@@ -747,7 +755,7 @@ class Temperature {
       static void reset_heater_idle_timer(const uint8_t e) {
         E_UNUSED();
         hotend_idle[HOTEND_INDEX].reset();
-        start_watching_heater(HOTEND_INDEX);
+        start_watching_hotend(HOTEND_INDEX);
       }
 
       #if HAS_HEATED_BED
@@ -806,7 +814,7 @@ class Temperature {
 
     static void checkExtruderAutoFans();
 
-    static float get_pid_output(const int8_t e);
+    static float get_pid_output_hotend(const uint8_t e);
 
     #if ENABLED(PIDTEMPBED)
       static float get_pid_output_bed();
@@ -816,9 +824,9 @@ class Temperature {
       static float get_pid_output_chamber();
     #endif
 
-    static void _temp_error(const int8_t e, PGM_P const serial_msg, PGM_P const lcd_msg);
-    static void min_temp_error(const int8_t e);
-    static void max_temp_error(const int8_t e);
+    static void _temp_error(const heater_ind_t e, PGM_P const serial_msg, PGM_P const lcd_msg);
+    static void min_temp_error(const heater_ind_t e);
+    static void max_temp_error(const heater_ind_t e);
 
     #if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED || ENABLED(THERMAL_PROTECTION_CHAMBER)
 
@@ -839,7 +847,7 @@ class Temperature {
         static tr_state_machine_t tr_state_machine_chamber;
       #endif
 
-      static void thermal_runaway_protection(tr_state_machine_t &state, const float &current, const float &target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc);
+      static void thermal_runaway_protection(tr_state_machine_t &state, const float &current, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc);
 
     #endif // THERMAL_PROTECTION
 };