Prusa MINI Firmware overview
Temperature Class Reference

#include <temperature.h>

Collaboration diagram for Temperature:

Public Member Functions

void init ()
 

Static Public Member Functions

static FORCE_INLINE bool tooColdToExtrude (const uint8_t)
 
static FORCE_INLINE bool targetTooColdToExtrude (const uint8_t)
 
static FORCE_INLINE bool hotEnoughToExtrude (const uint8_t e)
 
static FORCE_INLINE bool targetHotEnoughToExtrude (const uint8_t e)
 
static void zero_fan_speeds ()
 
static void readings_ready ()
 
static void isr ()
 
static void manage_heater () _O2
 
static FORCE_INLINE float degHotend (const uint8_t E_NAME)
 
static FORCE_INLINE int16_t degTargetHotend (const uint8_t E_NAME)
 
static void start_watching_hotend (const uint8_t=0)
 
static void start_watching_chamber ()
 
static int16_t getHeaterPower (const heater_ind_t heater)
 
static void disable_all_heaters ()
 
static void PID_autotune (const float &target, const heater_ind_t hotend, const int8_t ncycles, const bool set_result=false)
 
static void reset_heater_idle_timer (const uint8_t E_NAME)
 
static void reset_bed_idle_timer ()
 
static void print_heater_states (const uint8_t target_extruder)
 

Static Public Attributes

static volatile bool in_temp_isr
 
static heater_idle_t hotend_idle [HOTENDS]
 
static heater_idle_t bed_idle
 
static heater_idle_t chamber_idle
 

Member Function Documentation

◆ tooColdToExtrude()

static FORCE_INLINE bool Temperature::tooColdToExtrude ( const uint8_t  )
static
314 { return false; }
Here is the caller graph for this function:

◆ targetTooColdToExtrude()

static FORCE_INLINE bool Temperature::targetTooColdToExtrude ( const uint8_t  )
static
315 { return false; }
Here is the caller graph for this function:

◆ hotEnoughToExtrude()

static FORCE_INLINE bool Temperature::hotEnoughToExtrude ( const uint8_t  e)
static
318 { return !tooColdToExtrude(e); }
Here is the call graph for this function:

◆ targetHotEnoughToExtrude()

static FORCE_INLINE bool Temperature::targetHotEnoughToExtrude ( const uint8_t  e)
static
319 { return !targetTooColdToExtrude(e); }
Here is the call graph for this function:

◆ init()

void Temperature::init ( )

Instance Methods

Initialize the temperature manager The manager is implemented by periodic calls to manage_heater()

1539  {
1540 
1541  #if EARLY_WATCHDOG
1542  // Flag that the thermalManager should be running
1543  if (inited) return;
1544  inited = true;
1545  #endif
1546 
1547  #if MB(RUMBA)
1548  #define _AD(N) (ANY(HEATER_##N##_USES_AD595, HEATER_##N##_USES_AD8495))
1549  #if _AD(0) || _AD(1) || _AD(2) || _AD(3) || _AD(4) || _AD(5) || _AD(BED) || _AD(CHAMBER)
1550  // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
1551  MCUCR = _BV(JTD);
1552  MCUCR = _BV(JTD);
1553  #endif
1554  #endif
1555 
1556  #if BOTH(PIDTEMP, PID_EXTRUSION_SCALING)
1557  last_e_position = 0;
1558  #endif
1559 
1560  #if HAS_HEATER_0
1561  #ifdef ALFAWISE_UX0
1562  OUT_WRITE_OD(HEATER_0_PIN, HEATER_0_INVERTING);
1563  #else
1564  OUT_WRITE(HEATER_0_PIN, HEATER_0_INVERTING);
1565  #endif
1566  #endif
1567 
1568  #if HAS_HEATER_1
1569  OUT_WRITE(HEATER_1_PIN, HEATER_1_INVERTING);
1570  #endif
1571  #if HAS_HEATER_2
1572  OUT_WRITE(HEATER_2_PIN, HEATER_2_INVERTING);
1573  #endif
1574  #if HAS_HEATER_3
1575  OUT_WRITE(HEATER_3_PIN, HEATER_3_INVERTING);
1576  #endif
1577  #if HAS_HEATER_4
1578  OUT_WRITE(HEATER_4_PIN, HEATER_4_INVERTING);
1579  #endif
1580  #if HAS_HEATER_5
1581  OUT_WRITE(HEATER_5_PIN, HEATER_5_INVERTING);
1582  #endif
1583 
1584  #if HAS_HEATED_BED
1585  #ifdef ALFAWISE_UX0
1586  OUT_WRITE_OD(HEATER_BED_PIN, HEATER_BED_INVERTING);
1587  #else
1588  OUT_WRITE(HEATER_BED_PIN, HEATER_BED_INVERTING);
1589  #endif
1590  #endif
1591 
1592  #if HAS_HEATED_CHAMBER
1593  OUT_WRITE(HEATER_CHAMBER_PIN, HEATER_CHAMBER_INVERTING);
1594  #endif
1595 
1596  #if HAS_FAN0
1598  #endif
1599  #if HAS_FAN1
1601  #endif
1602  #if HAS_FAN2
1604  #endif
1605  #if ENABLED(USE_CONTROLLER_FAN)
1607  #endif
1608 
1609  #if MAX6675_SEPARATE_SPI
1610 
1611  OUT_WRITE(SCK_PIN, LOW);
1614 
1615  max6675_spi.init();
1616 
1617  OUT_WRITE(SS_PIN, HIGH);
1619 
1620  #endif
1621 
1622  #if ENABLED(HEATER_1_USES_MAX6675)
1624  #endif
1625 
1626  HAL_adc_init();
1627 
1628  #if HAS_TEMP_ADC_0
1630  #endif
1631  #if HAS_TEMP_ADC_1
1633  #endif
1634  #if HAS_TEMP_ADC_2
1636  #endif
1637  #if HAS_TEMP_ADC_3
1639  #endif
1640  #if HAS_TEMP_ADC_4
1642  #endif
1643  #if HAS_TEMP_ADC_5
1645  #endif
1646  #if HAS_JOY_ADC_X
1647  HAL_ANALOG_SELECT(JOY_X_PIN);
1648  #endif
1649  #if HAS_JOY_ADC_Y
1650  HAL_ANALOG_SELECT(JOY_Y_PIN);
1651  #endif
1652  #if HAS_JOY_ADC_Z
1653  HAL_ANALOG_SELECT(JOY_Z_PIN);
1654  #endif
1655  #if HAS_JOY_ADC_EN
1656  SET_INPUT_PULLUP(JOY_EN_PIN);
1657  #endif
1658  #if HAS_HEATED_BED
1660  #endif
1661  #if HAS_TEMP_CHAMBER
1663  #endif
1664  #if ENABLED(FILAMENT_WIDTH_SENSOR)
1666  #endif
1667  #if HAS_ADC_BUTTONS
1668  HAL_ANALOG_SELECT(ADC_KEYPAD_PIN);
1669  #endif
1670 
1673 
1674  #if HAS_AUTO_FAN_0
1676  #endif
1677  #if HAS_AUTO_FAN_1 && !_EFANOVERLAP(1,0)
1679  #endif
1680  #if HAS_AUTO_FAN_2 && !(_EFANOVERLAP(2,0) || _EFANOVERLAP(2,1))
1682  #endif
1683  #if HAS_AUTO_FAN_3 && !(_EFANOVERLAP(3,0) || _EFANOVERLAP(3,1) || _EFANOVERLAP(3,2))
1685  #endif
1686  #if HAS_AUTO_FAN_4 && !(_EFANOVERLAP(4,0) || _EFANOVERLAP(4,1) || _EFANOVERLAP(4,2) || _EFANOVERLAP(4,3))
1688  #endif
1689  #if HAS_AUTO_FAN_5 && !(_EFANOVERLAP(5,0) || _EFANOVERLAP(5,1) || _EFANOVERLAP(5,2) || _EFANOVERLAP(5,3) || _EFANOVERLAP(5,4))
1691  #endif
1692  #if HAS_AUTO_CHAMBER_FAN && !AUTO_CHAMBER_IS_E
1694  #endif
1695 
1696  // Wait for temperature measurement to settle
1697  delay(250);
1698 
1699  #if HOTENDS
1700 
1701  #define _TEMP_MIN_E(NR) do{ \
1702  temp_range[NR].mintemp = HEATER_ ##NR## _MINTEMP; \
1703  while (analog_to_celsius_hotend(temp_range[NR].raw_min, NR) < HEATER_ ##NR## _MINTEMP) \
1704  temp_range[NR].raw_min += TEMPDIR(NR) * (OVERSAMPLENR); \
1705  }while(0)
1706  #define _TEMP_MAX_E(NR) do{ \
1707  temp_range[NR].maxtemp = HEATER_ ##NR## _MAXTEMP; \
1708  while (analog_to_celsius_hotend(temp_range[NR].raw_max, NR) > HEATER_ ##NR## _MAXTEMP) \
1709  temp_range[NR].raw_max -= TEMPDIR(NR) * (OVERSAMPLENR); \
1710  }while(0)
1711 
1712  #ifdef HEATER_0_MINTEMP
1713  _TEMP_MIN_E(0);
1714  #endif
1715  #ifdef HEATER_0_MAXTEMP
1716  _TEMP_MAX_E(0);
1717  #endif
1718  #if HOTENDS > 1
1719  #ifdef HEATER_1_MINTEMP
1720  _TEMP_MIN_E(1);
1721  #endif
1722  #ifdef HEATER_1_MAXTEMP
1723  _TEMP_MAX_E(1);
1724  #endif
1725  #if HOTENDS > 2
1726  #ifdef HEATER_2_MINTEMP
1727  _TEMP_MIN_E(2);
1728  #endif
1729  #ifdef HEATER_2_MAXTEMP
1730  _TEMP_MAX_E(2);
1731  #endif
1732  #if HOTENDS > 3
1733  #ifdef HEATER_3_MINTEMP
1734  _TEMP_MIN_E(3);
1735  #endif
1736  #ifdef HEATER_3_MAXTEMP
1737  _TEMP_MAX_E(3);
1738  #endif
1739  #if HOTENDS > 4
1740  #ifdef HEATER_4_MINTEMP
1741  _TEMP_MIN_E(4);
1742  #endif
1743  #ifdef HEATER_4_MAXTEMP
1744  _TEMP_MAX_E(4);
1745  #endif
1746  #if HOTENDS > 5
1747  #ifdef HEATER_5_MINTEMP
1748  _TEMP_MIN_E(5);
1749  #endif
1750  #ifdef HEATER_5_MAXTEMP
1751  _TEMP_MAX_E(5);
1752  #endif
1753  #endif // HOTENDS > 5
1754  #endif // HOTENDS > 4
1755  #endif // HOTENDS > 3
1756  #endif // HOTENDS > 2
1757  #endif // HOTENDS > 1
1758 
1759  #endif // HOTENDS
1760 
1761  #if HAS_HEATED_BED
1762  #ifdef BED_MINTEMP
1763  while (analog_to_celsius_bed(mintemp_raw_BED) < BED_MINTEMP) mintemp_raw_BED += TEMPDIR(BED) * (OVERSAMPLENR);
1764  #endif
1765  #ifdef BED_MAXTEMP
1766  while (analog_to_celsius_bed(maxtemp_raw_BED) > BED_MAXTEMP) maxtemp_raw_BED -= TEMPDIR(BED) * (OVERSAMPLENR);
1767  #endif
1768  #endif // HAS_HEATED_BED
1769 
1770  #if HAS_HEATED_CHAMBER
1771  #ifdef CHAMBER_MINTEMP
1772  while (analog_to_celsius_chamber(mintemp_raw_CHAMBER) < CHAMBER_MINTEMP) mintemp_raw_CHAMBER += TEMPDIR(CHAMBER) * (OVERSAMPLENR);
1773  #endif
1774  #ifdef CHAMBER_MAXTEMP
1775  while (analog_to_celsius_chamber(maxtemp_raw_CHAMBER) > CHAMBER_MAXTEMP) maxtemp_raw_CHAMBER -= TEMPDIR(CHAMBER) * (OVERSAMPLENR);
1776  #endif
1777  #endif
1778 
1779  #if ENABLED(PROBING_HEATERS_OFF)
1780  paused = false;
1781  #endif
1782 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ zero_fan_speeds()

static void Temperature::zero_fan_speeds ( )
static

Static (class) methods

506  {
507  #if FAN_COUNT > 0
508  FANS_LOOP(i) set_fan_speed(i, 0);
509  #endif
510  }
Here is the caller graph for this function:

◆ readings_ready()

void Temperature::readings_ready ( )
static

Called from the Temperature ISR

2182  {
2183 
2184  // Update the raw values if they've been read. Else we could be updating them during reading.
2185  if (!temp_meas_ready) set_current_temp_raw();
2186 
2187  // Filament Sensor - can be read any time since IIR filtering is used
2188  #if ENABLED(FILAMENT_WIDTH_SENSOR)
2190  #endif
2191 
2192  #if HOTENDS
2193  HOTEND_LOOP() temp_hotend[e].reset();
2194  #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
2195  temp_hotend[1].reset();
2196  #endif
2197  #endif
2198 
2199  #if HAS_HEATED_BED
2200  temp_bed.reset();
2201  #endif
2202 
2203  #if HAS_TEMP_CHAMBER
2204  temp_chamber.reset();
2205  #endif
2206 
2207  #if HAS_JOY_ADC_X
2208  joystick.x.reset();
2209  #endif
2210  #if HAS_JOY_ADC_Y
2211  joystick.y.reset();
2212  #endif
2213  #if HAS_JOY_ADC_Z
2214  joystick.z.reset();
2215  #endif
2216 
2217  #if HOTENDS
2218 
2219  static constexpr int8_t temp_dir[] = {
2220  #if ENABLED(HEATER_0_USES_MAX6675)
2221  0
2222  #else
2223  TEMPDIR(0)
2224  #endif
2225  #if HOTENDS > 1
2226  #if ENABLED(HEATER_1_USES_MAX6675)
2227  , 0
2228  #else
2229  , TEMPDIR(1)
2230  #endif
2231  #if HOTENDS > 2
2232  , TEMPDIR(2)
2233  #if HOTENDS > 3
2234  , TEMPDIR(3)
2235  #if HOTENDS > 4
2236  , TEMPDIR(4)
2237  #if HOTENDS > 5
2238  , TEMPDIR(5)
2239  #endif // HOTENDS > 5
2240  #endif // HOTENDS > 4
2241  #endif // HOTENDS > 3
2242  #endif // HOTENDS > 2
2243  #endif // HOTENDS > 1
2244  };
2245 
2246  for (uint8_t e = 0; e < COUNT(temp_dir); e++) {
2247  const int8_t tdir = temp_dir[e];
2248  if (tdir) {
2249  const int16_t rawtemp = temp_hotend[e].raw * tdir; // normal direction, +rawtemp, else -rawtemp
2250  const bool heater_on = (temp_hotend[e].target > 0
2251  #if ENABLED(PIDTEMP)
2252  || temp_hotend[e].soft_pwm_amount > 0
2253  #endif
2254  );
2255  if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e);
2256  if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) {
2257  #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
2258  if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
2259  #endif
2260  min_temp_error((heater_ind_t)e);
2261  }
2262  #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
2263  else
2264  consecutive_low_temperature_error[e] = 0;
2265  #endif
2266  }
2267  }
2268 
2269  #endif // HOTENDS
2270 
2271  #if HAS_HEATED_BED
2272  #if TEMPDIR(BED) < 0
2273  #define BEDCMP(A,B) ((A)<=(B))
2274  #else
2275  #define BEDCMP(A,B) ((A)>=(B))
2276  #endif
2277  const bool bed_on = (temp_bed.target > 0)
2278  #if ENABLED(PIDTEMPBED)
2279  || (temp_bed.soft_pwm_amount > 0)
2280  #endif
2281  ;
2282  if (BEDCMP(temp_bed.raw, maxtemp_raw_BED)) max_temp_error(H_BED);
2283  if (bed_on && BEDCMP(mintemp_raw_BED, temp_bed.raw)) min_temp_error(H_BED);
2284  #endif
2285 
2286  #if HAS_HEATED_CHAMBER
2287  #if TEMPDIR(CHAMBER) < 0
2288  #define CHAMBERCMP(A,B) ((A)<=(B))
2289  #else
2290  #define CHAMBERCMP(A,B) ((A)>=(B))
2291  #endif
2292  const bool chamber_on = (temp_chamber.target > 0);
2293  if (CHAMBERCMP(temp_chamber.raw, maxtemp_raw_CHAMBER)) max_temp_error(H_CHAMBER);
2294  if (chamber_on && CHAMBERCMP(mintemp_raw_CHAMBER, temp_chamber.raw)) min_temp_error(H_CHAMBER);
2295  #endif
2296 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isr()

void Temperature::isr ( )
static

Standard heater PWM modulation

One sensor is sampled on every other call of the ISR. Each sensor is read 16 (OVERSAMPLENR) times, taking the average.

On each Prepare pass, ADC is started for a sensor pin. On the next pass, the ADC value is read and accumulated.

This gives each ADC 0.9765ms to charge up.

2346  {
2347 
2348  static int8_t temp_count = -1;
2349  static ADCSensorState adc_sensor_state = StartupDelay;
2350  static uint8_t pwm_count = _BV(SOFT_PWM_SCALE);
2351  // avoid multiple loads of pwm_count
2352  uint8_t pwm_count_tmp = pwm_count;
2353 
2354  #if HAS_ADC_BUTTONS
2355  static unsigned int raw_ADCKey_value = 0;
2356  static bool ADCKey_pressed = false;
2357  #endif
2358 
2359  #if HOTENDS
2360  static SoftPWM soft_pwm_hotend[HOTENDS];
2361  #endif
2362 
2363  #if HAS_HEATED_BED
2364  static SoftPWM soft_pwm_bed;
2365  #endif
2366 
2367  #if HAS_HEATED_CHAMBER
2368  static SoftPWM soft_pwm_chamber;
2369  #endif
2370 
2371  #if DISABLED(SLOW_PWM_HEATERS)
2372 
2373  #if HOTENDS || HAS_HEATED_BED || HAS_HEATED_CHAMBER
2374  constexpr uint8_t pwm_mask =
2375  #if ENABLED(SOFT_PWM_DITHER)
2376  _BV(SOFT_PWM_SCALE) - 1
2377  #else
2378  0
2379  #endif
2380  ;
2381  #define _PWM_MOD(N,S,T) do{ \
2382  const bool on = S.add(pwm_mask, T.soft_pwm_amount); \
2383  WRITE_HEATER_##N(on); \
2384  }while(0)
2385  #endif
2386 
2387  /**
2388  * Standard heater PWM modulation
2389  */
2390  if (pwm_count_tmp >= 127) {
2391  pwm_count_tmp -= 127;
2392 
2393  #if HOTENDS
2394  #define _PWM_MOD_E(N) _PWM_MOD(N,soft_pwm_hotend[N],temp_hotend[N])
2395  _PWM_MOD_E(0);
2396  #if HOTENDS > 1
2397  _PWM_MOD_E(1);
2398  #if HOTENDS > 2
2399  _PWM_MOD_E(2);
2400  #if HOTENDS > 3
2401  _PWM_MOD_E(3);
2402  #if HOTENDS > 4
2403  _PWM_MOD_E(4);
2404  #if HOTENDS > 5
2405  _PWM_MOD_E(5);
2406  #endif // HOTENDS > 5
2407  #endif // HOTENDS > 4
2408  #endif // HOTENDS > 3
2409  #endif // HOTENDS > 2
2410  #endif // HOTENDS > 1
2411  #endif // HOTENDS
2412 
2413  #if HAS_HEATED_BED
2414  _PWM_MOD(BED,soft_pwm_bed,temp_bed);
2415  #endif
2416 
2417  #if HAS_HEATED_CHAMBER
2418  _PWM_MOD(CHAMBER,soft_pwm_chamber,temp_chamber);
2419  #endif
2420 
2421  #if ENABLED(FAN_SOFT_PWM)
2422  #define _FAN_PWM(N) do{ \
2423  uint8_t &spcf = soft_pwm_count_fan[N]; \
2424  spcf = (spcf & pwm_mask) + (soft_pwm_amount_fan[N] >> 1); \
2425  WRITE_FAN(N, spcf > pwm_mask ? HIGH : LOW); \
2426  }while(0)
2427  #if HAS_FAN0
2428  _FAN_PWM(0);
2429  #endif
2430  #if HAS_FAN1
2431  _FAN_PWM(1);
2432  #endif
2433  #if HAS_FAN2
2434  _FAN_PWM(2);
2435  #endif
2436  #endif
2437  }
2438  else {
2439  #define _PWM_LOW(N,S) do{ if (S.count <= pwm_count_tmp) WRITE_HEATER_##N(LOW); }while(0)
2440  #if HOTENDS
2441  #define _PWM_LOW_E(N) _PWM_LOW(N, soft_pwm_hotend[N])
2442  _PWM_LOW_E(0);
2443  #if HOTENDS > 1
2444  _PWM_LOW_E(1);
2445  #if HOTENDS > 2
2446  _PWM_LOW_E(2);
2447  #if HOTENDS > 3
2448  _PWM_LOW_E(3);
2449  #if HOTENDS > 4
2450  _PWM_LOW_E(4);
2451  #if HOTENDS > 5
2452  _PWM_LOW_E(5);
2453  #endif // HOTENDS > 5
2454  #endif // HOTENDS > 4
2455  #endif // HOTENDS > 3
2456  #endif // HOTENDS > 2
2457  #endif // HOTENDS > 1
2458  #endif // HOTENDS
2459 
2460  #if HAS_HEATED_BED
2461  _PWM_LOW(BED, soft_pwm_bed);
2462  #endif
2463 
2464  #if HAS_HEATED_CHAMBER
2465  _PWM_LOW(CHAMBER, soft_pwm_chamber);
2466  #endif
2467 
2468  #if ENABLED(FAN_SOFT_PWM)
2469  #if HAS_FAN0
2470  if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(0, LOW);
2471  #endif
2472  #if HAS_FAN1
2473  if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN(1, LOW);
2474  #endif
2475  #if HAS_FAN2
2476  if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN(2, LOW);
2477  #endif
2478  #endif
2479  }
2480 
2481  // SOFT_PWM_SCALE to frequency:
2482  //
2483  // 0: 16000000/64/256/128 = 7.6294 Hz
2484  // 1: / 64 = 15.2588 Hz
2485  // 2: / 32 = 30.5176 Hz
2486  // 3: / 16 = 61.0352 Hz
2487  // 4: / 8 = 122.0703 Hz
2488  // 5: / 4 = 244.1406 Hz
2489  pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE);
2490 
2491  #else // SLOW_PWM_HEATERS
2492 
2493  /**
2494  * SLOW PWM HEATERS
2495  *
2496  * For relay-driven heaters
2497  */
2498  #define _SLOW_SET(NR,PWM,V) do{ if (PWM.ready(V)) WRITE_HEATER_##NR(V); }while(0)
2499  #define _SLOW_PWM(NR,PWM,SRC) do{ PWM.count = SRC.soft_pwm_amount; _SLOW_SET(NR,PWM,(PWM.count > 0)); }while(0)
2500  #define _PWM_OFF(NR,PWM) do{ if (PWM.count < slow_pwm_count) _SLOW_SET(NR,PWM,0); }while(0)
2501 
2502  static uint8_t slow_pwm_count = 0;
2503 
2504  if (slow_pwm_count == 0) {
2505 
2506  #if HOTENDS
2507  #define _SLOW_PWM_E(N) _SLOW_PWM(N, soft_pwm_hotend[N], temp_hotend[N])
2508  _SLOW_PWM_E(0);
2509  #if HOTENDS > 1
2510  _SLOW_PWM_E(1);
2511  #if HOTENDS > 2
2512  _SLOW_PWM_E(2);
2513  #if HOTENDS > 3
2514  _SLOW_PWM_E(3);
2515  #if HOTENDS > 4
2516  _SLOW_PWM_E(4);
2517  #if HOTENDS > 5
2518  _SLOW_PWM_E(5);
2519  #endif // HOTENDS > 5
2520  #endif // HOTENDS > 4
2521  #endif // HOTENDS > 3
2522  #endif // HOTENDS > 2
2523  #endif // HOTENDS > 1
2524  #endif // HOTENDS
2525 
2526  #if HAS_HEATED_BED
2527  _SLOW_PWM(BED, soft_pwm_bed, temp_bed);
2528  #endif
2529 
2530  } // slow_pwm_count == 0
2531 
2532  #if HOTENDS
2533  #define _PWM_OFF_E(N) _PWM_OFF(N, soft_pwm_hotend[N]);
2534  _PWM_OFF_E(0);
2535  #if HOTENDS > 1
2536  _PWM_OFF_E(1);
2537  #if HOTENDS > 2
2538  _PWM_OFF_E(2);
2539  #if HOTENDS > 3
2540  _PWM_OFF_E(3);
2541  #if HOTENDS > 4
2542  _PWM_OFF_E(4);
2543  #if HOTENDS > 5
2544  _PWM_OFF_E(5);
2545  #endif // HOTENDS > 5
2546  #endif // HOTENDS > 4
2547  #endif // HOTENDS > 3
2548  #endif // HOTENDS > 2
2549  #endif // HOTENDS > 1
2550  #endif // HOTENDS
2551 
2552  #if HAS_HEATED_BED
2553  _PWM_OFF(BED, soft_pwm_bed);
2554  #endif
2555 
2556  #if ENABLED(FAN_SOFT_PWM)
2557  if (pwm_count_tmp >= 127) {
2558  pwm_count_tmp = 0;
2559  #define _PWM_FAN(N) do{ \
2560  soft_pwm_count_fan[N] = soft_pwm_amount_fan[N] >> 1; \
2561  WRITE_FAN(N, soft_pwm_count_fan[N] > 0 ? HIGH : LOW); \
2562  }while(0)
2563  #if HAS_FAN0
2564  _PWM_FAN(0);
2565  #endif
2566  #if HAS_FAN1
2567  _PWM_FAN(1);
2568  #endif
2569  #if HAS_FAN2
2570  _PWM_FAN(2);
2571  #endif
2572  }
2573  #if HAS_FAN0
2574  if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(0, LOW);
2575  #endif
2576  #if HAS_FAN1
2577  if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN(1, LOW);
2578  #endif
2579  #if HAS_FAN2
2580  if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN(2, LOW);
2581  #endif
2582  #endif // FAN_SOFT_PWM
2583 
2584  // SOFT_PWM_SCALE to frequency:
2585  //
2586  // 0: 16000000/64/256/128 = 7.6294 Hz
2587  // 1: / 64 = 15.2588 Hz
2588  // 2: / 32 = 30.5176 Hz
2589  // 3: / 16 = 61.0352 Hz
2590  // 4: / 8 = 122.0703 Hz
2591  // 5: / 4 = 244.1406 Hz
2592  pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE);
2593 
2594  // increment slow_pwm_count only every 64th pwm_count,
2595  // i.e. yielding a PWM frequency of 16/128 Hz (8s).
2596  if (((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0) {
2597  slow_pwm_count++;
2598  slow_pwm_count &= 0x7F;
2599 
2600  #if HOTENDS
2601  soft_pwm_hotend[0].dec();
2602  #if HOTENDS > 1
2603  soft_pwm_hotend[1].dec();
2604  #if HOTENDS > 2
2605  soft_pwm_hotend[2].dec();
2606  #if HOTENDS > 3
2607  soft_pwm_hotend[3].dec();
2608  #if HOTENDS > 4
2609  soft_pwm_hotend[4].dec();
2610  #if HOTENDS > 5
2611  soft_pwm_hotend[5].dec();
2612  #endif // HOTENDS > 5
2613  #endif // HOTENDS > 4
2614  #endif // HOTENDS > 3
2615  #endif // HOTENDS > 2
2616  #endif // HOTENDS > 1
2617  #endif // HOTENDS
2618  #if HAS_HEATED_BED
2619  soft_pwm_bed.dec();
2620  #endif
2621  } // ((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0
2622 
2623  #endif // SLOW_PWM_HEATERS
2624 
2625  //
2626  // Update lcd buttons 488 times per second
2627  //
2628  static bool do_buttons;
2629  if ((do_buttons ^= true)) ui.update_buttons();
2630 
2631  /**
2632  * One sensor is sampled on every other call of the ISR.
2633  * Each sensor is read 16 (OVERSAMPLENR) times, taking the average.
2634  *
2635  * On each Prepare pass, ADC is started for a sensor pin.
2636  * On the next pass, the ADC value is read and accumulated.
2637  *
2638  * This gives each ADC 0.9765ms to charge up.
2639  */
2640  #define ACCUMULATE_ADC(obj) do{ \
2641  if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; \
2642  else obj.sample(HAL_READ_ADC()); \
2643  }while(0)
2644 
2645  ADCSensorState next_sensor_state = adc_sensor_state < SensorsReady ? (ADCSensorState)(int(adc_sensor_state) + 1) : StartSampling;
2646 
2647  switch (adc_sensor_state) {
2648 
2649  case SensorsReady: {
2650  // All sensors have been read. Stay in this state for a few
2651  // ISRs to save on calls to temp update/checking code below.
2652  constexpr int8_t extra_loops = MIN_ADC_ISR_LOOPS - (int8_t)SensorsReady;
2653  static uint8_t delay_count = 0;
2654  if (extra_loops > 0) {
2655  if (delay_count == 0) delay_count = extra_loops; // Init this delay
2656  if (--delay_count) // While delaying...
2657  next_sensor_state = SensorsReady; // retain this state (else, next state will be 0)
2658  break;
2659  }
2660  else {
2661  adc_sensor_state = StartSampling; // Fall-through to start sampling
2662  next_sensor_state = (ADCSensorState)(int(StartSampling) + 1);
2663  }
2664  }
2665 
2666  case StartSampling: // Start of sampling loops. Do updates/checks.
2667  if (++temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
2668  temp_count = 0;
2669  readings_ready();
2670  }
2671  break;
2672 
2673  #if HAS_TEMP_ADC_0
2674  case PrepareTemp_0: HAL_START_ADC(TEMP_0_PIN); break;
2675  case MeasureTemp_0: ACCUMULATE_ADC(temp_hotend[0]); break;
2676  #endif
2677 
2678  #if HAS_HEATED_BED
2679  case PrepareTemp_BED: HAL_START_ADC(TEMP_BED_PIN); break;
2680  case MeasureTemp_BED: ACCUMULATE_ADC(temp_bed); break;
2681  #endif
2682 
2683  #if HAS_TEMP_CHAMBER
2684  case PrepareTemp_CHAMBER: HAL_START_ADC(TEMP_CHAMBER_PIN); break;
2685  case MeasureTemp_CHAMBER: ACCUMULATE_ADC(temp_chamber); break;
2686  #endif
2687 
2688  #if HAS_TEMP_ADC_1
2689  case PrepareTemp_1: HAL_START_ADC(TEMP_1_PIN); break;
2690  case MeasureTemp_1: ACCUMULATE_ADC(temp_hotend[1]); break;
2691  #endif
2692 
2693  #if HAS_TEMP_ADC_2
2694  case PrepareTemp_2: HAL_START_ADC(TEMP_2_PIN); break;
2695  case MeasureTemp_2: ACCUMULATE_ADC(temp_hotend[2]); break;
2696  #endif
2697 
2698  #if HAS_TEMP_ADC_3
2699  case PrepareTemp_3: HAL_START_ADC(TEMP_3_PIN); break;
2700  case MeasureTemp_3: ACCUMULATE_ADC(temp_hotend[3]); break;
2701  #endif
2702 
2703  #if HAS_TEMP_ADC_4
2704  case PrepareTemp_4: HAL_START_ADC(TEMP_4_PIN); break;
2705  case MeasureTemp_4: ACCUMULATE_ADC(temp_hotend[4]); break;
2706  #endif
2707 
2708  #if HAS_TEMP_ADC_5
2709  case PrepareTemp_5: HAL_START_ADC(TEMP_5_PIN); break;
2710  case MeasureTemp_5: ACCUMULATE_ADC(temp_hotend[5]); break;
2711  #endif
2712 
2713  #if ENABLED(FILAMENT_WIDTH_SENSOR)
2714  case Prepare_FILWIDTH: HAL_START_ADC(FILWIDTH_PIN); break;
2715  case Measure_FILWIDTH:
2716  if (!HAL_ADC_READY())
2717  next_sensor_state = adc_sensor_state; // redo this state
2718  else
2720  break;
2721  #endif
2722 
2723  #if HAS_JOY_ADC_X
2724  case PrepareJoy_X: HAL_START_ADC(JOY_X_PIN); break;
2725  case MeasureJoy_X: ACCUMULATE_ADC(joystick.x); break;
2726  #endif
2727 
2728  #if HAS_JOY_ADC_Y
2729  case PrepareJoy_Y: HAL_START_ADC(JOY_Y_PIN); break;
2730  case MeasureJoy_Y: ACCUMULATE_ADC(joystick.y); break;
2731  #endif
2732 
2733  #if HAS_JOY_ADC_Z
2734  case PrepareJoy_Z: HAL_START_ADC(JOY_Z_PIN); break;
2735  case MeasureJoy_Z: ACCUMULATE_ADC(joystick.z); break;
2736  #endif
2737 
2738  #if HAS_ADC_BUTTONS
2739  case Prepare_ADC_KEY: HAL_START_ADC(ADC_KEYPAD_PIN); break;
2740  case Measure_ADC_KEY:
2741  if (!HAL_ADC_READY())
2742  next_sensor_state = adc_sensor_state; // redo this state
2743  else if (ADCKey_count < 16) {
2744  raw_ADCKey_value = HAL_READ_ADC();
2745  if (raw_ADCKey_value <= 900) {
2746  NOMORE(current_ADCKey_raw, raw_ADCKey_value);
2747  ADCKey_count++;
2748  }
2749  else { //ADC Key release
2750  if (ADCKey_count > 0) ADCKey_count++; else ADCKey_pressed = false;
2751  if (ADCKey_pressed) {
2752  ADCKey_count = 0;
2753  current_ADCKey_raw = 1024;
2754  }
2755  }
2756  }
2757  if (ADCKey_count == 16) ADCKey_pressed = true;
2758  break;
2759  #endif // ADC_KEYPAD
2760 
2761  case StartupDelay: break;
2762 
2763  } // switch(adc_sensor_state)
2764 
2765  // Go to the next state
2766  adc_sensor_state = next_sensor_state;
2767 
2768  //
2769  // Additional ~1KHz Tasks
2770  //
2771 
2772  #if ENABLED(BABYSTEPPING)
2773  babystep.task();
2774  #endif
2775 
2776  // Poll endstops state, if required
2777  endstops.poll();
2778 
2779  // Periodically call the planner timer
2780  planner.tick();
2781 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ manage_heater()

void Temperature::manage_heater ( )
static

Call periodically to manage heaters

Manage heating activities for extruder hot-ends and a heated bed

  • Acquire updated temperature readings
    • Also resets the watchdog timer
  • Invoke thermal runaway protection
  • Manage extruder auto-fan
  • Apply filament width to the extrusion rate (may move)
  • Update the heated bed PID output value
975  {
976 
977  #if EARLY_WATCHDOG
978  // If thermal manager is still not running, make sure to at least reset the watchdog!
979  if (!inited) return watchdog_refresh();
980  #endif
981 
982  #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING)
983  static bool last_pause_state;
984  #endif
985 
986  #if ENABLED(EMERGENCY_PARSER)
988  #endif
989 
990  if (!temp_meas_ready) return;
991 
992  updateTemperaturesFromRawValues(); // also resets the watchdog
993 
994  #if ENABLED(HEATER_0_USES_MAX6675)
995  if (temp_hotend[0].celsius > _MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(H_E0);
996  if (temp_hotend[0].celsius < _MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(H_E0);
997  #endif
998 
999  #if ENABLED(HEATER_1_USES_MAX6675)
1000  if (temp_hotend[1].celsius > _MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(H_E1);
1001  if (temp_hotend[1].celsius < _MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(H_E1);
1002  #endif
1003 
1004  millis_t ms = millis();
1005 
1006  #if HOTENDS
1007 
1008  HOTEND_LOOP() {
1009  #if ENABLED(THERMAL_PROTECTION_HOTENDS)
1010  if (degHotend(e) > temp_range[e].maxtemp)
1011  _temp_error((heater_ind_t)e, PSTR(MSG_T_THERMAL_RUNAWAY), GET_TEXT(MSG_THERMAL_RUNAWAY));
1012  #endif
1013 
1014  #if HEATER_IDLE_HANDLER
1015  hotend_idle[e].update(ms);
1016  #endif
1017 
1018  #if ENABLED(THERMAL_PROTECTION_HOTENDS)
1019  // Check for thermal runaway
1020  thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
1021  #endif
1022 
1023  temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0;
1024 
1025  #if WATCH_HOTENDS
1026  // Make sure temperature is increasing
1027  if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder?
1028  if (degHotend(e) < watch_hotend[e].target) // Failed to increase enough?
1029  _temp_error((heater_ind_t)e, PSTR(MSG_T_HEATING_FAILED), GET_TEXT(MSG_HEATING_FAILED_LCD));
1030  else // Start again if the target is still far off
1032  }
1033  #endif
1034 
1035  #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
1036  // Make sure measured temperatures are close together
1037  if (ABS(temp_hotend[0].celsius - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF)
1038  _temp_error(H_E0, PSTR(MSG_REDUNDANCY), GET_TEXT(MSG_ERR_REDUNDANT_TEMP));
1039  #endif
1040 
1041  } // HOTEND_LOOP
1042 
1043  #endif // HOTENDS
1044 
1045  #if HAS_AUTO_FAN
1046  if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently
1047  checkExtruderAutoFans();
1048  next_auto_fan_check_ms = ms + 2500UL;
1049  }
1050  #endif
1051 
1052  #if ENABLED(FILAMENT_WIDTH_SENSOR)
1053  /**
1054  * Dynamically set the volumetric multiplier based
1055  * on the delayed Filament Width measurement.
1056  */
1058  #endif
1059 
1060  #if HAS_HEATED_BED
1061 
1062  #if ENABLED(THERMAL_PROTECTION_BED)
1063  if (degBed() > BED_MAXTEMP)
1064  _temp_error(H_BED, PSTR(MSG_T_THERMAL_RUNAWAY), GET_TEXT(MSG_THERMAL_RUNAWAY));
1065  #endif
1066 
1067  #if WATCH_BED
1068  // Make sure temperature is increasing
1069  if (watch_bed.elapsed(ms)) { // Time to check the bed?
1070  if (degBed() < watch_bed.target) // Failed to increase enough?
1071  _temp_error(H_BED, PSTR(MSG_T_HEATING_FAILED), GET_TEXT(MSG_HEATING_FAILED_LCD));
1072  else // Start again if the target is still far off
1073  start_watching_bed();
1074  }
1075  #endif // WATCH_BED
1076 
1077  do {
1078 
1079  #if DISABLED(PIDTEMPBED)
1080  if (PENDING(ms, next_bed_check_ms)
1081  #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING)
1082  && paused == last_pause_state
1083  #endif
1084  ) break;
1085  next_bed_check_ms = ms + BED_CHECK_INTERVAL;
1086  #if BOTH(PROBING_HEATERS_OFF, BED_LIMIT_SWITCHING)
1087  last_pause_state = paused;
1088  #endif
1089  #endif
1090 
1091  #if HEATER_IDLE_HANDLER
1092  bed_idle.update(ms);
1093  #endif
1094 
1095  #if HAS_THERMALLY_PROTECTED_BED
1096  thermal_runaway_protection(tr_state_machine_bed, temp_bed.celsius, temp_bed.target, H_BED, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
1097  #endif
1098 
1099  #if HEATER_IDLE_HANDLER
1100  if (bed_idle.timed_out) {
1101  temp_bed.soft_pwm_amount = 0;
1102  #if DISABLED(PIDTEMPBED)
1103  WRITE_HEATER_BED(LOW);
1104  #endif
1105  }
1106  else
1107  #endif
1108  {
1109  #if ENABLED(PIDTEMPBED)
1110  temp_bed.soft_pwm_amount = WITHIN(temp_bed.celsius, BED_MINTEMP, BED_MAXTEMP) ? (int)get_pid_output_bed() >> 1 : 0;
1111  #else
1112  // Check if temperature is within the correct band
1113  if (WITHIN(temp_bed.celsius, BED_MINTEMP, BED_MAXTEMP)) {
1114  #if ENABLED(BED_LIMIT_SWITCHING)
1115  if (temp_bed.celsius >= temp_bed.target + BED_HYSTERESIS)
1116  temp_bed.soft_pwm_amount = 0;
1117  else if (temp_bed.celsius <= temp_bed.target - (BED_HYSTERESIS))
1118  temp_bed.soft_pwm_amount = MAX_BED_POWER >> 1;
1119  #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING
1120  temp_bed.soft_pwm_amount = temp_bed.celsius < temp_bed.target ? MAX_BED_POWER >> 1 : 0;
1121  #endif
1122  }
1123  else {
1124  temp_bed.soft_pwm_amount = 0;
1125  WRITE_HEATER_BED(LOW);
1126  }
1127  #endif
1128  }
1129 
1130  } while (false);
1131 
1132  #endif // HAS_HEATED_BED
1133 
1134  #if HAS_HEATED_CHAMBER
1135 
1136  #ifndef CHAMBER_CHECK_INTERVAL
1137  #define CHAMBER_CHECK_INTERVAL 1000UL
1138  #endif
1139 
1140  #if ENABLED(THERMAL_PROTECTION_CHAMBER)
1141  if (degChamber() > CHAMBER_MAXTEMP)
1142  _temp_error(H_CHAMBER, PSTR(MSG_T_THERMAL_RUNAWAY), GET_TEXT(MSG_THERMAL_RUNAWAY));
1143  #endif
1144 
1145  #if WATCH_CHAMBER
1146  // Make sure temperature is increasing
1147  if (watch_chamber.elapsed(ms)) { // Time to check the chamber?
1148  if (degChamber() < watch_chamber.target) // Failed to increase enough?
1149  _temp_error(H_CHAMBER, PSTR(MSG_T_HEATING_FAILED), GET_TEXT(MSG_HEATING_FAILED_LCD));
1150  else
1151  start_watching_chamber(); // Start again if the target is still far off
1152  }
1153  #endif
1154 
1155  if (ELAPSED(ms, next_chamber_check_ms)) {
1156  next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL;
1157 
1158  if (WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP)) {
1159  #if ENABLED(CHAMBER_LIMIT_SWITCHING)
1160  if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS)
1161  temp_chamber.soft_pwm_amount = 0;
1162  else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS))
1163  temp_chamber.soft_pwm_amount = MAX_CHAMBER_POWER >> 1;
1164  #else
1165  temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? MAX_CHAMBER_POWER >> 1 : 0;
1166  #endif
1167  }
1168  else {
1169  temp_chamber.soft_pwm_amount = 0;
1170  WRITE_HEATER_CHAMBER(LOW);
1171  }
1172 
1173  #if ENABLED(THERMAL_PROTECTION_CHAMBER)
1174  thermal_runaway_protection(tr_state_machine_chamber, temp_chamber.celsius, temp_chamber.target, H_CHAMBER, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS);
1175  #endif
1176  }
1177 
1178  // TODO: Implement true PID pwm
1179  //temp_bed.soft_pwm_amount = WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP) ? (int)get_pid_output_chamber() >> 1 : 0;
1180 
1181  #endif // HAS_HEATED_CHAMBER
1182 
1183  UNUSED(ms);
1184 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ degHotend()

static FORCE_INLINE float Temperature::degHotend ( const uint8_t  E_NAME)
static
544  {
545  return (0
546  #if HOTENDS
547  + temp_hotend[HOTEND_INDEX].celsius
548  #endif
549  );
550  }
Here is the caller graph for this function:

◆ degTargetHotend()

static FORCE_INLINE int16_t Temperature::degTargetHotend ( const uint8_t  E_NAME)
static
562  {
563  return (0
564  #if HOTENDS
565  + temp_hotend[HOTEND_INDEX].target
566  #endif
567  );
568  }
Here is the caller graph for this function:

◆ start_watching_hotend()

static void Temperature::start_watching_hotend ( const uint8_t  = 0)
static
573 {}
Here is the caller graph for this function:

◆ start_watching_chamber()

static void Temperature::start_watching_chamber ( )
static
670 {}
Here is the caller graph for this function:

◆ getHeaterPower()

int16_t Temperature::getHeaterPower ( const heater_ind_t  heater_id)
static

The software PWM power for a heater

Class and Instance Methods

607  {
608  switch (heater_id) {
609  #if HAS_HEATED_BED
610  case H_BED: return temp_bed.soft_pwm_amount;
611  #endif
612  #if HAS_HEATED_CHAMBER
613  case H_CHAMBER: return temp_chamber.soft_pwm_amount;
614  #endif
615  default:
616  #if HOTENDS
617  return temp_hotend[heater_id].soft_pwm_amount;
618  #else
619  return 0;
620  #endif
621  }
622 }

◆ disable_all_heaters()

void Temperature::disable_all_heaters ( )
static

Switch off all heaters, set all target temperatures to 0

1926  {
1927 
1928  #if ENABLED(AUTOTEMP)
1929  planner.autotemp_enabled = false;
1930  #endif
1931 
1932  #if HOTENDS
1933  HOTEND_LOOP() setTargetHotend(0, e);
1934  #endif
1935 
1936  #if HAS_HEATED_BED
1937  setTargetBed(0);
1938  #endif
1939 
1940  #if HAS_HEATED_CHAMBER
1941  setTargetChamber(0);
1942  #endif
1943 
1944  // Unpause and reset everything
1945  #if ENABLED(PROBING_HEATERS_OFF)
1946  pause(false);
1947  #endif
1948 
1949  #define DISABLE_HEATER(NR) { \
1950  setTargetHotend(0, NR); \
1951  temp_hotend[NR].soft_pwm_amount = 0; \
1952  WRITE_HEATER_ ##NR (LOW); \
1953  }
1954 
1955  #if HAS_TEMP_HOTEND
1956  DISABLE_HEATER(0);
1957  #if HOTENDS > 1
1958  DISABLE_HEATER(1);
1959  #if HOTENDS > 2
1960  DISABLE_HEATER(2);
1961  #if HOTENDS > 3
1962  DISABLE_HEATER(3);
1963  #if HOTENDS > 4
1964  DISABLE_HEATER(4);
1965  #if HOTENDS > 5
1966  DISABLE_HEATER(5);
1967  #endif // HOTENDS > 5
1968  #endif // HOTENDS > 4
1969  #endif // HOTENDS > 3
1970  #endif // HOTENDS > 2
1971  #endif // HOTENDS > 1
1972  #endif
1973 
1974  #if HAS_HEATED_BED
1975  temp_bed.target = 0;
1976  temp_bed.soft_pwm_amount = 0;
1977  WRITE_HEATER_BED(LOW);
1978  #endif
1979 
1980  #if HAS_HEATED_CHAMBER
1981  temp_chamber.target = 0;
1982  temp_chamber.soft_pwm_amount = 0;
1983  WRITE_HEATER_CHAMBER(LOW);
1984  #endif
1985 }
Here is the caller graph for this function:

◆ PID_autotune()

static void Temperature::PID_autotune ( const float &  target,
const heater_ind_t  hotend,
const int8_t  ncycles,
const bool  set_result = false 
)
static

Perform auto-tuning for hotend or bed in response to M303

◆ reset_heater_idle_timer()

static void Temperature::reset_heater_idle_timer ( const uint8_t  E_NAME)
static

Update the temp manager when PID values change

Here is the call graph for this function:

◆ reset_bed_idle_timer()

static void Temperature::reset_bed_idle_timer ( )
static
734  {
735  bed_idle.reset();
736  start_watching_bed();
737  }
Here is the call graph for this function:

◆ print_heater_states()

static void Temperature::print_heater_states ( const uint8_t  target_extruder)
static

Member Data Documentation

◆ in_temp_isr

volatile bool Temperature::in_temp_isr
static

◆ hotend_idle

heater_idle_t Temperature::hotend_idle[HOTENDS]
static

◆ bed_idle

heater_idle_t Temperature::bed_idle
static

◆ chamber_idle

heater_idle_t Temperature::chamber_idle
static
ACCUMULATE_ADC
#define ACCUMULATE_ADC(obj)
WITHIN
#define WITHIN(N, L, H)
Definition: macros.h:195
PENDING
#define PENDING(NOW, SOON)
Definition: millis_t.h:28
GET_TEXT
#define GET_TEXT(MSG)
Definition: multi_language.h:72
Temperature::tooColdToExtrude
static FORCE_INLINE bool tooColdToExtrude(const uint8_t)
Definition: temperature.h:314
MAX_BED_POWER
#define MAX_BED_POWER
Definition: Configuration_A3ides_2209_MINI.h:481
HEATER_BED_PIN
#define HEATER_BED_PIN
Definition: pins_ESP32.h:83
CHAMBER_MAXTEMP
#define CHAMBER_MAXTEMP
Definition: Configuration_A3ides_2209_MINI.h:397
TEMPDIR
#define TEMPDIR(N)
Definition: temperature.cpp:267
heater_idle_t::update
void update(const millis_t &ms)
Definition: temperature.h:201
FAN1_PIN
#define FAN1_PIN
Definition: pins_AZSMZ_MINI.h:87
StartupDelay
Definition: temperature.h:134
PIDTEMPBED
#define PIDTEMPBED
Definition: Configuration_A3ides_2209_MINI.h:471
OUT_WRITE
#define OUT_WRITE(IO, V)
Definition: fastio.h:108
INIT_CHAMBER_AUTO_FAN_PIN
#define INIT_CHAMBER_AUTO_FAN_PIN(P)
Definition: temperature.cpp:1530
HEATER_CHAMBER_PIN
#define HEATER_CHAMBER_PIN
Definition: Configuration_A3ides_2209_MINI.h:355
E0_AUTO_FAN_PIN
#define E0_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:285
HEATER_1_MINTEMP
#define HEATER_1_MINTEMP
Definition: Configuration_A3ides_2209_MINI.h:379
FAN2_PIN
#define FAN2_PIN
Definition: pins_CHEAPTRONICv2.h:92
LOW
#define LOW
Definition: wiring_constants.h:70
heater_idle_t::reset
void reset()
Definition: temperature.h:203
HAL_READ_ADC
#define HAL_READ_ADC()
Definition: HAL.h:360
INIT_FAN_PIN
#define INIT_FAN_PIN(P)
Definition: temperature.cpp:1523
_MAX
#define _MAX(V...)
Definition: macros.h:346
E1_AUTO_FAN_PIN
#define E1_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:286
HEATER_0_MINTEMP
#define HEATER_0_MINTEMP
Definition: Configuration_A3ides_2209_MINI.h:378
TEMP_TIMER_NUM
#define TEMP_TIMER_NUM
Definition: HAL.h:128
babystep
Babystep babystep
i
uint8_t i
Definition: screen_test_graph.c:72
_MIN
#define _MIN(V...)
Definition: macros.h:333
MIN_ADC_ISR_LOOPS
#define MIN_ADC_ISR_LOOPS
Definition: temperature.h:140
TEMP_BED_PIN
#define TEMP_BED_PIN
Definition: pins_ESP32.h:76
BED_MAXTEMP
#define BED_MAXTEMP
Definition: Configuration_A3ides_2209_MINI.h:396
kill
void kill(PGM_P const lcd_error, PGM_P const lcd_component, const bool steppers_off)
Definition: Marlin.cpp:718
millis
uint32_t millis(void)
Definition: wiring_time.c:29
StartSampling
Definition: temperature.h:93
TEMP_2_PIN
#define TEMP_2_PIN
Definition: pins_MKS_SBASE.h:96
EmergencyParser::killed_by_M112
static bool killed_by_M112
Definition: emergency_parser.h:65
Temperature::degHotend
static FORCE_INLINE float degHotend(const uint8_t E_NAME)
Definition: temperature.h:544
HAL_timer_start
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t)
Definition: HAL.h:149
ADCSensorState
ADCSensorState
Definition: temperature.h:92
Endstops::poll
static void poll()
Definition: endstops.cpp:272
emergency_parser
EmergencyParser emergency_parser
OUT_WRITE_OD
#define OUT_WRITE_OD(IO, V)
Definition: fastio.h:115
HAL_ADC_READY
#define HAL_ADC_READY()
Definition: HAL.h:361
HEATER_2_PIN
#define HEATER_2_PIN
Definition: pins_COHESION3D_REMIX.h:116
NOMORE
#define NOMORE(v, n)
Definition: macros.h:133
FAN_PIN
#define FAN_PIN
Definition: pins_ESP32.h:82
SET_INPUT_PULLUP
#define SET_INPUT_PULLUP(IO)
Definition: fastio.h:100
ABS
#define ABS(a)
Definition: macros.h:266
E2_AUTO_FAN_PIN
#define E2_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:287
HEATER_0_PIN
#define HEATER_0_PIN
Definition: pins_ESP32.h:81
HEATER_3_PIN
#define HEATER_3_PIN
Definition: pins_CNCONTROLS_11.h:68
SensorsReady
Definition: temperature.h:133
TEMP_TIMER_FREQUENCY
#define TEMP_TIMER_FREQUENCY
Definition: HAL.h:131
PSTR
#define PSTR(str)
Definition: pgmspace.h:31
E4_AUTO_FAN_PIN
#define E4_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:289
Temperature::targetTooColdToExtrude
static FORCE_INLINE bool targetTooColdToExtrude(const uint8_t)
Definition: temperature.h:315
FILWIDTH_PIN
#define FILWIDTH_PIN
Definition: pins_RAMPS_LINUX.h:211
ENABLE_TEMPERATURE_INTERRUPT
#define ENABLE_TEMPERATURE_INTERRUPT()
Definition: HAL.h:145
H_E0
Definition: temperature.h:52
COUNT
#define COUNT(a)
Definition: macros.h:200
filwidth
FilamentWidthSensor filwidth
TEMP_CHAMBER_PIN
#define TEMP_CHAMBER_PIN
Definition: pins_CNCONTROLS_15.h:54
HAL_START_ADC
#define HAL_START_ADC(pin)
Definition: HAL.h:357
HEATER_5_PIN
#define HEATER_5_PIN
Definition: pins.h:757
Temperature::hotend_idle
static heater_idle_t hotend_idle[HOTENDS]
Definition: temperature.h:322
FilamentWidthSensor::update_volumetric
static void update_volumetric()
Definition: filwidth.h:108
HEATER_0_MAXTEMP
#define HEATER_0_MAXTEMP
Definition: Configuration_A3ides_2209_MINI.h:390
E3_AUTO_FAN_PIN
#define E3_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:288
FilamentWidthSensor::accumulate
static void accumulate(const uint16_t adc)
Definition: filwidth.h:63
MISO_PIN
#define MISO_PIN
Definition: spi_pins.h:58
HEATER_1_PIN
#define HEATER_1_PIN
Definition: pins_RAMPS_LINUX.h:196
heater_idle_t::timed_out
bool timed_out
Definition: temperature.h:200
HOTEND_LOOP
#define HOTEND_LOOP()
Definition: Conditionals_LCD.h:436
H_BED
Definition: temperature.h:51
TEMP_CHAMBER_HYSTERESIS
#define TEMP_CHAMBER_HYSTERESIS
Definition: Configuration_A3ides_2209_MINI.h:374
_PWM_LOW
#define _PWM_LOW(N, S)
ELAPSED
#define ELAPSED(NOW, SOON)
Definition: millis_t.h:29
HEATER_4_PIN
#define HEATER_4_PIN
Definition: pins.h:754
MAX6675_SS2_PIN
#define MAX6675_SS2_PIN
Definition: pins_MIGHTYBOARD_REVE.h:142
uint8_t
const uint8_t[]
Definition: 404_html.c:3
TEMP_3_PIN
#define TEMP_3_PIN
Definition: pins_RAMPS_RE_ARM.h:169
MAX_REDUNDANT_TEMP_SENSOR_DIFF
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF
Definition: Configuration_A3ides_2209_MINI.h:364
_PWM_MOD
#define _PWM_MOD(N, S, T)
Babystep::task
static void task()
ui
MarlinUI ui
FilamentWidthSensor::reading_ready
static void reading_ready()
Definition: filwidth.h:74
SCK_PIN
#define SCK_PIN
Definition: spi_pins.h:55
_BV
#define _BV(bit)
Definition: wiring_constants.h:99
HAL_adc_init
void HAL_adc_init()
Definition: HAL.h:345
H_CHAMBER
Definition: temperature.h:51
delay
void delay(uint32_t ms)
Definition: wiring_time.c:42
HAL_ANALOG_SELECT
#define HAL_ANALOG_SELECT(pin)
Definition: HAL.h:342
MSG_REDUNDANCY
#define MSG_REDUNDANCY
Definition: language.h:292
INIT_E_AUTO_FAN_PIN
#define INIT_E_AUTO_FAN_PIN(P)
Definition: temperature.cpp:1525
OVERSAMPLENR
#define OVERSAMPLENR
Definition: thermistors.h:26
E5_AUTO_FAN_PIN
#define E5_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:290
MOSI_PIN
#define MOSI_PIN
Definition: spi_pins.h:61
Temperature::start_watching_hotend
static void start_watching_hotend(const uint8_t=0)
Definition: temperature.h:573
CHAMBER_MINTEMP
#define CHAMBER_MINTEMP
Definition: Configuration_A3ides_2209_MINI.h:385
Temperature::bed_idle
static heater_idle_t bed_idle
Definition: temperature.h:324
HEATER_1_MAXTEMP
#define HEATER_1_MAXTEMP
Definition: Configuration_A3ides_2209_MINI.h:391
HIGH
#define HIGH
Definition: wiring_constants.h:71
DISABLE_HEATER
#define DISABLE_HEATER(NR)
Temperature::start_watching_chamber
static void start_watching_chamber()
Definition: temperature.h:670
MAX6675_SS_PIN
#define MAX6675_SS_PIN
Definition: pins_RAMPS_LINUX.h:138
TEMP_1_PIN
#define TEMP_1_PIN
Definition: pins_RAMPS_LINUX.h:131
CHAMBER_AUTO_FAN_PIN
#define CHAMBER_AUTO_FAN_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:291
BED_MINTEMP
#define BED_MINTEMP
Definition: Configuration_A3ides_2209_MINI.h:384
joystick
Joystick joystick
createSpeedLookupTable.int
int
Definition: createSpeedLookupTable.py:15
HOTENDS
#define HOTENDS
Definition: Conditionals_LCD.h:425
TEMP_5_PIN
#define TEMP_5_PIN
Definition: pins.h:779
BOTH
#define BOTH(V1, V2)
Definition: macros.h:183
H_E1
Definition: temperature.h:52
TEMP_0_PIN
#define TEMP_0_PIN
Definition: pins_ESP32.h:75
SS_PIN
#define SS_PIN
Definition: spi_pins.h:64
Temperature::readings_ready
static void readings_ready()
Definition: temperature.cpp:2182
is_preheating
#define is_preheating(n)
Definition: temperature.h:537
Planner::tick
static void tick()
Definition: planner.h:750
_PWM_FAN
#define _PWM_FAN
Definition: hwio_a3ides.h:43
MSG_T_THERMAL_RUNAWAY
#define MSG_T_THERMAL_RUNAWAY
Definition: language.h:294
UNUSED
#define UNUSED(X)
Definition: stm32f4xx_hal_def.h:74
endstops
Endstops endstops
Definition: endstops.cpp:51
watchdog_refresh
void watchdog_refresh()
Definition: HAL.h:28
millis_t
uint32_t millis_t
Definition: millis_t.h:26
CONTROLLER_FAN_PIN
#define CONTROLLER_FAN_PIN
Definition: pins_MEGACONTROLLER.h:121
TEMP_4_PIN
#define TEMP_4_PIN
Definition: pins.h:776
SoftPWM
Definition: temperature.cpp:2325
heater_ind_t
heater_ind_t
Definition: temperature.h:49
MSG_T_HEATING_FAILED
#define MSG_T_HEATING_FAILED
Definition: language.h:293
ENABLED
#define ENABLED(V...)
Definition: macros.h:177
planner
Planner planner
Definition: planner.cpp:111
HOTEND_INDEX
#define HOTEND_INDEX
Definition: temperature.h:41
SOFT_PWM_SCALE
#define SOFT_PWM_SCALE
Definition: Configuration_A3ides_2209_MINI.h:1986