My Marlin configs for Fabrikator Mini and CTC i3 Pro B
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

temperature.cpp 91KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * temperature.cpp - temperature control
  24. */
  25. #include "temperature.h"
  26. #include "endstops.h"
  27. #include "../Marlin.h"
  28. #include "../lcd/ultralcd.h"
  29. #include "planner.h"
  30. #include "../core/language.h"
  31. #include "../HAL/shared/Delay.h"
  32. #define MAX6675_SEPARATE_SPI (ENABLED(HEATER_0_USES_MAX6675) || ENABLED(HEATER_1_USES_MAX6675)) && PIN_EXISTS(MAX6675_SCK) && PIN_EXISTS(MAX6675_DO)
  33. #if MAX6675_SEPARATE_SPI
  34. #include "../libs/private_spi.h"
  35. #endif
  36. #if ENABLED(BABYSTEPPING) || ENABLED(PID_EXTRUSION_SCALING)
  37. #include "stepper.h"
  38. #endif
  39. #include "printcounter.h"
  40. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  41. #include "../feature/filwidth.h"
  42. #endif
  43. #if ENABLED(EMERGENCY_PARSER)
  44. #include "../feature/emergency_parser.h"
  45. #endif
  46. #if ENABLED(PRINTER_EVENT_LEDS)
  47. #include "../feature/leds/printer_event_leds.h"
  48. #endif
  49. #if ENABLED(SINGLENOZZLE)
  50. #include "tool_change.h"
  51. #endif
  52. #if HOTEND_USES_THERMISTOR
  53. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  54. static void* heater_ttbl_map[2] = { (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE };
  55. static constexpr uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
  56. #else
  57. static void* heater_ttbl_map[HOTENDS] = ARRAY_BY_HOTENDS((void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE, (void*)HEATER_2_TEMPTABLE, (void*)HEATER_3_TEMPTABLE, (void*)HEATER_4_TEMPTABLE);
  58. static constexpr uint8_t heater_ttbllen_map[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN, HEATER_3_TEMPTABLE_LEN, HEATER_4_TEMPTABLE_LEN);
  59. #endif
  60. #endif
  61. Temperature thermalManager;
  62. /**
  63. * Macros to include the heater id in temp errors. The compiler's dead-code
  64. * elimination should (hopefully) optimize out the unused strings.
  65. */
  66. #if HAS_HEATED_BED
  67. #define TEMP_ERR_PSTR(MSG, E) \
  68. (E) == -1 ? PSTR(MSG ## _BED) : \
  69. (HOTENDS > 1 && (E) == 1) ? PSTR(MSG_E2 " " MSG) : \
  70. (HOTENDS > 2 && (E) == 2) ? PSTR(MSG_E3 " " MSG) : \
  71. (HOTENDS > 3 && (E) == 3) ? PSTR(MSG_E4 " " MSG) : \
  72. (HOTENDS > 4 && (E) == 4) ? PSTR(MSG_E5 " " MSG) : \
  73. (HOTENDS > 5 && (E) == 5) ? PSTR(MSG_E6 " " MSG) : \
  74. PSTR(MSG_E1 " " MSG)
  75. #else
  76. #define TEMP_ERR_PSTR(MSG, E) \
  77. (HOTENDS > 1 && (E) == 1) ? PSTR(MSG_E2 " " MSG) : \
  78. (HOTENDS > 2 && (E) == 2) ? PSTR(MSG_E3 " " MSG) : \
  79. (HOTENDS > 3 && (E) == 3) ? PSTR(MSG_E4 " " MSG) : \
  80. (HOTENDS > 4 && (E) == 4) ? PSTR(MSG_E5 " " MSG) : \
  81. (HOTENDS > 5 && (E) == 5) ? PSTR(MSG_E6 " " MSG) : \
  82. PSTR(MSG_E1 " " MSG)
  83. #endif
  84. // public:
  85. #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING)
  86. bool Temperature::adaptive_fan_slowing = true;
  87. #endif
  88. float Temperature::current_temperature[HOTENDS]; // = { 0.0 };
  89. int16_t Temperature::current_temperature_raw[HOTENDS], // = { 0 }
  90. Temperature::target_temperature[HOTENDS]; // = { 0 }
  91. #if ENABLED(AUTO_POWER_E_FANS)
  92. uint8_t Temperature::autofan_speed[HOTENDS]; // = { 0 }
  93. #endif
  94. #if FAN_COUNT > 0
  95. uint8_t Temperature::fan_speed[FAN_COUNT]; // = { 0 }
  96. #if ENABLED(EXTRA_FAN_SPEED)
  97. uint8_t Temperature::old_fan_speed[FAN_COUNT], Temperature::new_fan_speed[FAN_COUNT];
  98. void Temperature::set_temp_fan_speed(const uint8_t fan, const uint16_t tmp_temp) {
  99. switch (tmp_temp) {
  100. case 1:
  101. set_fan_speed(fan, old_fan_speed[fan]);
  102. break;
  103. case 2:
  104. old_fan_speed[fan] = fan_speed[fan];
  105. set_fan_speed(fan, new_fan_speed[fan]);
  106. break;
  107. default:
  108. new_fan_speed[fan] = MIN(tmp_temp, 255U);
  109. break;
  110. }
  111. }
  112. #endif
  113. #if ENABLED(PROBING_FANS_OFF)
  114. bool Temperature::fans_paused; // = false;
  115. uint8_t Temperature::paused_fan_speed[FAN_COUNT]; // = { 0 }
  116. #endif
  117. #if ENABLED(ADAPTIVE_FAN_SLOWING)
  118. uint8_t Temperature::fan_speed_scaler[FAN_COUNT] = ARRAY_N(FAN_COUNT, 128, 128, 128, 128, 128, 128);
  119. #endif
  120. #if HAS_LCD_MENU
  121. uint8_t Temperature::lcd_tmpfan_speed[
  122. #if ENABLED(SINGLENOZZLE)
  123. MAX(EXTRUDERS, FAN_COUNT)
  124. #else
  125. FAN_COUNT
  126. #endif
  127. ]; // = { 0 }
  128. #endif
  129. void Temperature::set_fan_speed(uint8_t target, uint16_t speed) {
  130. NOMORE(speed, 255U);
  131. #if ENABLED(SINGLENOZZLE)
  132. if (target != active_extruder) {
  133. if (target < EXTRUDERS) singlenozzle_fan_speed[target] = speed;
  134. return;
  135. }
  136. target = 0; // Always use fan index 0 with SINGLENOZZLE
  137. #endif
  138. if (target >= FAN_COUNT) return;
  139. fan_speed[target] = speed;
  140. #if HAS_LCD_MENU
  141. lcd_tmpfan_speed[target] = speed;
  142. #endif
  143. }
  144. #if ENABLED(PROBING_FANS_OFF)
  145. void Temperature::set_fans_paused(const bool p) {
  146. if (p != fans_paused) {
  147. fans_paused = p;
  148. if (p)
  149. for (uint8_t x = 0; x < FAN_COUNT; x++) {
  150. paused_fan_speed[x] = fan_speed[x];
  151. fan_speed[x] = 0;
  152. }
  153. else
  154. for (uint8_t x = 0; x < FAN_COUNT; x++)
  155. fan_speed[x] = paused_fan_speed[x];
  156. }
  157. }
  158. #endif // PROBING_FANS_OFF
  159. #endif // FAN_COUNT > 0
  160. #if HAS_HEATED_BED
  161. float Temperature::current_temperature_bed = 0.0;
  162. int16_t Temperature::current_temperature_bed_raw = 0,
  163. Temperature::target_temperature_bed = 0;
  164. uint8_t Temperature::soft_pwm_amount_bed;
  165. #ifdef BED_MINTEMP
  166. int16_t Temperature::bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP;
  167. #endif
  168. #ifdef BED_MAXTEMP
  169. int16_t Temperature::bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
  170. #endif
  171. #if WATCH_THE_BED
  172. uint16_t Temperature::watch_target_bed_temp = 0;
  173. millis_t Temperature::watch_bed_next_ms = 0;
  174. #endif
  175. #if ENABLED(PIDTEMPBED)
  176. PID_t Temperature::bed_pid; // Initialized by settings.load()
  177. #else
  178. millis_t Temperature::next_bed_check_ms;
  179. #endif
  180. uint16_t Temperature::raw_temp_bed_value = 0;
  181. #if HEATER_IDLE_HANDLER
  182. millis_t Temperature::bed_idle_timeout_ms = 0;
  183. bool Temperature::bed_idle_timeout_exceeded = false;
  184. #endif
  185. #endif // HAS_HEATED_BED
  186. #if HAS_TEMP_CHAMBER
  187. float Temperature::current_temperature_chamber = 0.0;
  188. int16_t Temperature::current_temperature_chamber_raw = 0;
  189. uint16_t Temperature::raw_temp_chamber_value = 0;
  190. #endif
  191. // Initialized by settings.load()
  192. #if ENABLED(PIDTEMP)
  193. hotend_pid_t Temperature::pid[HOTENDS];
  194. #endif
  195. #if ENABLED(BABYSTEPPING)
  196. volatile int16_t Temperature::babystepsTodo[XYZ] = { 0 };
  197. #endif
  198. #if WATCH_HOTENDS
  199. uint16_t Temperature::watch_target_temp[HOTENDS] = { 0 };
  200. millis_t Temperature::watch_heater_next_ms[HOTENDS] = { 0 };
  201. #endif
  202. #if ENABLED(PREVENT_COLD_EXTRUSION)
  203. bool Temperature::allow_cold_extrude = false;
  204. int16_t Temperature::extrude_min_temp = EXTRUDE_MINTEMP;
  205. #endif
  206. // private:
  207. #if EARLY_WATCHDOG
  208. bool Temperature::inited = false;
  209. #endif
  210. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  211. uint16_t Temperature::redundant_temperature_raw = 0;
  212. float Temperature::redundant_temperature = 0.0;
  213. #endif
  214. volatile bool Temperature::temp_meas_ready = false;
  215. #if ENABLED(PIDTEMP)
  216. #if ENABLED(PID_EXTRUSION_SCALING)
  217. long Temperature::last_e_position;
  218. long Temperature::lpq[LPQ_MAX_LEN];
  219. int Temperature::lpq_ptr = 0;
  220. #endif
  221. #endif
  222. uint16_t Temperature::raw_temp_value[MAX_EXTRUDERS] = { 0 };
  223. // Init min and max temp with extreme values to prevent false errors during startup
  224. int16_t Temperature::minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP, HEATER_4_RAW_LO_TEMP),
  225. Temperature::maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP, HEATER_4_RAW_HI_TEMP),
  226. Temperature::minttemp[HOTENDS] = { 0 },
  227. Temperature::maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
  228. #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
  229. uint8_t Temperature::consecutive_low_temperature_error[HOTENDS] = { 0 };
  230. #endif
  231. #ifdef MILLISECONDS_PREHEAT_TIME
  232. millis_t Temperature::preheat_end_time[HOTENDS] = { 0 };
  233. #endif
  234. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  235. int8_t Temperature::meas_shift_index; // Index of a delayed sample in buffer
  236. #endif
  237. #if HAS_AUTO_FAN
  238. millis_t Temperature::next_auto_fan_check_ms = 0;
  239. #endif
  240. uint8_t Temperature::soft_pwm_amount[HOTENDS];
  241. #if ENABLED(FAN_SOFT_PWM)
  242. uint8_t Temperature::soft_pwm_amount_fan[FAN_COUNT],
  243. Temperature::soft_pwm_count_fan[FAN_COUNT];
  244. #endif
  245. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  246. uint16_t Temperature::current_raw_filwidth = 0; // Measured filament diameter - one extruder only
  247. #endif
  248. #if ENABLED(PROBING_HEATERS_OFF)
  249. bool Temperature::paused;
  250. #endif
  251. #if HEATER_IDLE_HANDLER
  252. millis_t Temperature::heater_idle_timeout_ms[HOTENDS] = { 0 };
  253. bool Temperature::heater_idle_timeout_exceeded[HOTENDS] = { false };
  254. #endif
  255. #if HAS_ADC_BUTTONS
  256. uint32_t Temperature::current_ADCKey_raw = 0;
  257. uint8_t Temperature::ADCKey_count = 0;
  258. #endif
  259. #if ENABLED(PID_EXTRUSION_SCALING)
  260. int16_t Temperature::lpq_len; // Initialized in configuration_store
  261. #endif
  262. #if HAS_PID_HEATING
  263. inline void say_default_() { SERIAL_ECHOPGM("#define DEFAULT_"); }
  264. /**
  265. * PID Autotuning (M303)
  266. *
  267. * Alternately heat and cool the nozzle, observing its behavior to
  268. * determine the best PID values to achieve a stable temperature.
  269. * Needs sufficient heater power to make some overshoot at target
  270. * temperature to succeed.
  271. */
  272. void Temperature::PID_autotune(const float &target, const int8_t heater, const int8_t ncycles, const bool set_result/*=false*/) {
  273. float current = 0.0;
  274. int cycles = 0;
  275. bool heating = true;
  276. millis_t next_temp_ms = millis(), t1 = next_temp_ms, t2 = next_temp_ms;
  277. long t_high = 0, t_low = 0;
  278. long bias, d;
  279. PID_t tune_pid = { 0, 0, 0 };
  280. float max = 0, min = 10000;
  281. #if HAS_PID_FOR_BOTH
  282. #define GHV(B,H) (heater < 0 ? (B) : (H))
  283. #define SHV(S,B,H) do{ if (heater < 0) S##_bed = B; else S [heater] = H; }while(0)
  284. #define ONHEATINGSTART() (heater < 0 ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart())
  285. #define ONHEATING(S,C,T) do{ if (heater < 0) printerEventLEDs.onBedHeating(S,C,T); else printerEventLEDs.onHotendHeating(S,C,T); }while(0)
  286. #elif ENABLED(PIDTEMPBED)
  287. #define GHV(B,H) B
  288. #define SHV(S,B,H) (S##_bed = B)
  289. #define ONHEATINGSTART() printerEventLEDs.onBedHeatingStart()
  290. #define ONHEATING(S,C,T) printerEventLEDs.onBedHeating(S,C,T)
  291. #else
  292. #define GHV(B,H) H
  293. #define SHV(S,B,H) (S [heater] = H)
  294. #define ONHEATINGSTART() printerEventLEDs.onHotendHeatingStart()
  295. #define ONHEATING(S,C,T) printerEventLEDs.onHotendHeating(S,C,T)
  296. #endif
  297. #if WATCH_THE_BED || WATCH_HOTENDS
  298. #define HAS_TP_BED (ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED))
  299. #if HAS_TP_BED && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
  300. #define GTV(B,H) (heater < 0 ? (B) : (H))
  301. #elif HAS_TP_BED
  302. #define GTV(B,H) (B)
  303. #else
  304. #define GTV(B,H) (H)
  305. #endif
  306. const uint16_t watch_temp_period = GTV(WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD);
  307. const uint8_t watch_temp_increase = GTV(WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
  308. const float watch_temp_target = target - float(watch_temp_increase + GTV(TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1);
  309. millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL;
  310. float next_watch_temp = 0.0;
  311. bool heated = false;
  312. #endif
  313. #if HAS_AUTO_FAN
  314. next_auto_fan_check_ms = next_temp_ms + 2500UL;
  315. #endif
  316. if (target > GHV(BED_MAXTEMP, maxttemp[heater]) - 15) {
  317. SERIAL_ECHOLNPGM(MSG_PID_TEMP_TOO_HIGH);
  318. return;
  319. }
  320. SERIAL_ECHOLNPGM(MSG_PID_AUTOTUNE_START);
  321. disable_all_heaters();
  322. SHV(soft_pwm_amount, bias = d = (MAX_BED_POWER) >> 1, bias = d = (PID_MAX) >> 1);
  323. wait_for_heatup = true; // Can be interrupted with M108
  324. #if ENABLED(PRINTER_EVENT_LEDS)
  325. const float start_temp = GHV(current_temperature_bed, current_temperature[heater]);
  326. LEDColor color = ONHEATINGSTART();
  327. #endif
  328. #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING)
  329. adaptive_fan_slowing = false;
  330. #endif
  331. // PID Tuning loop
  332. while (wait_for_heatup) {
  333. const millis_t ms = millis();
  334. if (temp_meas_ready) { // temp sample ready
  335. updateTemperaturesFromRawValues();
  336. // Get the current temperature and constrain it
  337. current = GHV(current_temperature_bed, current_temperature[heater]);
  338. NOLESS(max, current);
  339. NOMORE(min, current);
  340. #if ENABLED(PRINTER_EVENT_LEDS)
  341. ONHEATING(start_temp, current, target);
  342. #endif
  343. #if HAS_AUTO_FAN
  344. if (ELAPSED(ms, next_auto_fan_check_ms)) {
  345. checkExtruderAutoFans();
  346. next_auto_fan_check_ms = ms + 2500UL;
  347. }
  348. #endif
  349. if (heating && current > target) {
  350. if (ELAPSED(ms, t2 + 5000UL)) {
  351. heating = false;
  352. SHV(soft_pwm_amount, (bias - d) >> 1, (bias - d) >> 1);
  353. t1 = ms;
  354. t_high = t1 - t2;
  355. max = target;
  356. }
  357. }
  358. if (!heating && current < target) {
  359. if (ELAPSED(ms, t1 + 5000UL)) {
  360. heating = true;
  361. t2 = ms;
  362. t_low = t2 - t1;
  363. if (cycles > 0) {
  364. const long max_pow = GHV(MAX_BED_POWER, PID_MAX);
  365. bias += (d * (t_high - t_low)) / (t_low + t_high);
  366. bias = constrain(bias, 20, max_pow - 20);
  367. d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias;
  368. SERIAL_ECHOPAIR(MSG_BIAS, bias);
  369. SERIAL_ECHOPAIR(MSG_D, d);
  370. SERIAL_ECHOPAIR(MSG_T_MIN, min);
  371. SERIAL_ECHOPAIR(MSG_T_MAX, max);
  372. if (cycles > 2) {
  373. float Ku = (4.0f * d) / (float(M_PI) * (max - min) * 0.5f),
  374. Tu = ((float)(t_low + t_high) * 0.001f);
  375. SERIAL_ECHOPAIR(MSG_KU, Ku);
  376. SERIAL_ECHOPAIR(MSG_TU, Tu);
  377. tune_pid.Kp = 0.6f * Ku;
  378. tune_pid.Ki = 2 * tune_pid.Kp / Tu;
  379. tune_pid.Kd = tune_pid.Kp * Tu * 0.125f;
  380. SERIAL_ECHOLNPGM("\n" MSG_CLASSIC_PID);
  381. SERIAL_ECHOPAIR(MSG_KP, tune_pid.Kp);
  382. SERIAL_ECHOPAIR(MSG_KI, tune_pid.Ki);
  383. SERIAL_ECHOLNPAIR(MSG_KD, tune_pid.Kd);
  384. /**
  385. tune_pid.Kp = 0.33*Ku;
  386. tune_pid.Ki = tune_pid.Kp/Tu;
  387. tune_pid.Kd = tune_pid.Kp*Tu/3;
  388. SERIAL_ECHOLNPGM(" Some overshoot");
  389. SERIAL_ECHOPAIR(" Kp: ", tune_pid.Kp);
  390. SERIAL_ECHOPAIR(" Ki: ", tune_pid.Ki);
  391. SERIAL_ECHOPAIR(" Kd: ", tune_pid.Kd);
  392. tune_pid.Kp = 0.2*Ku;
  393. tune_pid.Ki = 2*tune_pid.Kp/Tu;
  394. tune_pid.Kd = tune_pid.Kp*Tu/3;
  395. SERIAL_ECHOLNPGM(" No overshoot");
  396. SERIAL_ECHOPAIR(" Kp: ", tune_pid.Kp);
  397. SERIAL_ECHOPAIR(" Ki: ", tune_pid.Ki);
  398. SERIAL_ECHOPAIR(" Kd: ", tune_pid.Kd);
  399. */
  400. }
  401. }
  402. SHV(soft_pwm_amount, (bias + d) >> 1, (bias + d) >> 1);
  403. cycles++;
  404. min = target;
  405. }
  406. }
  407. }
  408. // Did the temperature overshoot very far?
  409. #ifndef MAX_OVERSHOOT_PID_AUTOTUNE
  410. #define MAX_OVERSHOOT_PID_AUTOTUNE 20
  411. #endif
  412. if (current > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
  413. SERIAL_ECHOLNPGM(MSG_PID_TEMP_TOO_HIGH);
  414. break;
  415. }
  416. // Report heater states every 2 seconds
  417. if (ELAPSED(ms, next_temp_ms)) {
  418. #if HAS_TEMP_SENSOR
  419. print_heater_states(heater >= 0 ? heater : active_extruder);
  420. SERIAL_EOL();
  421. #endif
  422. next_temp_ms = ms + 2000UL;
  423. // Make sure heating is actually working
  424. #if WATCH_THE_BED || WATCH_HOTENDS
  425. if (
  426. #if WATCH_THE_BED && WATCH_HOTENDS
  427. true
  428. #elif WATCH_HOTENDS
  429. heater >= 0
  430. #else
  431. heater < 0
  432. #endif
  433. ) {
  434. if (!heated) { // If not yet reached target...
  435. if (current > next_watch_temp) { // Over the watch temp?
  436. next_watch_temp = current + watch_temp_increase; // - set the next temp to watch for
  437. temp_change_ms = ms + watch_temp_period * 1000UL; // - move the expiration timer up
  438. if (current > watch_temp_target) heated = true; // - Flag if target temperature reached
  439. }
  440. else if (ELAPSED(ms, temp_change_ms)) // Watch timer expired
  441. _temp_error(heater, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, heater));
  442. }
  443. else if (current < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) // Heated, then temperature fell too far?
  444. _temp_error(heater, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, heater));
  445. }
  446. #endif
  447. } // every 2 seconds
  448. // Timeout after MAX_CYCLE_TIME_PID_AUTOTUNE minutes since the last undershoot/overshoot cycle
  449. #ifndef MAX_CYCLE_TIME_PID_AUTOTUNE
  450. #define MAX_CYCLE_TIME_PID_AUTOTUNE 20L
  451. #endif
  452. if (((ms - t1) + (ms - t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) {
  453. SERIAL_ECHOLNPGM(MSG_PID_TIMEOUT);
  454. break;
  455. }
  456. if (cycles > ncycles && cycles > 2) {
  457. SERIAL_ECHOLNPGM(MSG_PID_AUTOTUNE_FINISHED);
  458. #if HAS_PID_FOR_BOTH
  459. const char * const estring = GHV(PSTR("bed"), PSTR(""));
  460. say_default_(); serialprintPGM(estring); SERIAL_ECHOLNPAIR("Kp ", tune_pid.Kp);
  461. say_default_(); serialprintPGM(estring); SERIAL_ECHOLNPAIR("Ki ", tune_pid.Ki);
  462. say_default_(); serialprintPGM(estring); SERIAL_ECHOLNPAIR("Kd ", tune_pid.Kd);
  463. #elif ENABLED(PIDTEMP)
  464. say_default_(); SERIAL_ECHOLNPAIR("Kp ", tune_pid.Kp);
  465. say_default_(); SERIAL_ECHOLNPAIR("Ki ", tune_pid.Ki);
  466. say_default_(); SERIAL_ECHOLNPAIR("Kd ", tune_pid.Kd);
  467. #else
  468. say_default_(); SERIAL_ECHOLNPAIR("bedKp ", tune_pid.Kp);
  469. say_default_(); SERIAL_ECHOLNPAIR("bedKi ", tune_pid.Ki);
  470. say_default_(); SERIAL_ECHOLNPAIR("bedKd ", tune_pid.Kd);
  471. #endif
  472. #define _SET_BED_PID() do { \
  473. bed_pid.Kp = tune_pid.Kp; \
  474. bed_pid.Ki = scalePID_i(tune_pid.Ki); \
  475. bed_pid.Kd = scalePID_d(tune_pid.Kd); \
  476. }while(0)
  477. #define _SET_EXTRUDER_PID() do { \
  478. PID_PARAM(Kp, heater) = tune_pid.Kp; \
  479. PID_PARAM(Ki, heater) = scalePID_i(tune_pid.Ki); \
  480. PID_PARAM(Kd, heater) = scalePID_d(tune_pid.Kd); \
  481. updatePID(); }while(0)
  482. // Use the result? (As with "M303 U1")
  483. if (set_result) {
  484. #if HAS_PID_FOR_BOTH
  485. if (heater < 0) _SET_BED_PID(); else _SET_EXTRUDER_PID();
  486. #elif ENABLED(PIDTEMP)
  487. _SET_EXTRUDER_PID();
  488. #else
  489. _SET_BED_PID();
  490. #endif
  491. }
  492. #if ENABLED(PRINTER_EVENT_LEDS)
  493. printerEventLEDs.onPidTuningDone(color);
  494. #endif
  495. goto EXIT_M303;
  496. }
  497. ui.update();
  498. }
  499. disable_all_heaters();
  500. #if ENABLED(PRINTER_EVENT_LEDS)
  501. printerEventLEDs.onPidTuningDone(color);
  502. #endif
  503. EXIT_M303:
  504. #if ENABLED(NO_FAN_SLOWING_IN_PID_TUNING)
  505. adaptive_fan_slowing = true;
  506. #endif
  507. return;
  508. }
  509. #endif // HAS_PID_HEATING
  510. /**
  511. * Class and Instance Methods
  512. */
  513. Temperature::Temperature() { }
  514. int Temperature::getHeaterPower(const int heater) {
  515. return (
  516. #if HAS_HEATED_BED
  517. heater < 0 ? soft_pwm_amount_bed :
  518. #endif
  519. soft_pwm_amount[heater]
  520. );
  521. }
  522. #if HAS_AUTO_FAN
  523. void Temperature::checkExtruderAutoFans() {
  524. static const pin_t fanPin[] PROGMEM = { E0_AUTO_FAN_PIN, E1_AUTO_FAN_PIN, E2_AUTO_FAN_PIN, E3_AUTO_FAN_PIN, E4_AUTO_FAN_PIN, E5_AUTO_FAN_PIN, CHAMBER_AUTO_FAN_PIN };
  525. static const uint8_t fanBit[] PROGMEM = {
  526. 0,
  527. AUTO_1_IS_0 ? 0 : 1,
  528. AUTO_2_IS_0 ? 0 : AUTO_2_IS_1 ? 1 : 2,
  529. AUTO_3_IS_0 ? 0 : AUTO_3_IS_1 ? 1 : AUTO_3_IS_2 ? 2 : 3,
  530. AUTO_4_IS_0 ? 0 : AUTO_4_IS_1 ? 1 : AUTO_4_IS_2 ? 2 : AUTO_4_IS_3 ? 3 : 4,
  531. AUTO_5_IS_0 ? 0 : AUTO_5_IS_1 ? 1 : AUTO_5_IS_2 ? 2 : AUTO_5_IS_3 ? 3 : AUTO_5_IS_4 ? 4 : 5,
  532. AUTO_CHAMBER_IS_0 ? 0 : AUTO_CHAMBER_IS_1 ? 1 : AUTO_CHAMBER_IS_2 ? 2 : AUTO_CHAMBER_IS_3 ? 3 : AUTO_CHAMBER_IS_4 ? 4 : 5
  533. };
  534. uint8_t fanState = 0;
  535. HOTEND_LOOP()
  536. if (current_temperature[e] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  537. SBI(fanState, pgm_read_byte(&fanBit[e]));
  538. #if HAS_TEMP_CHAMBER
  539. if (current_temperature_chamber > EXTRUDER_AUTO_FAN_TEMPERATURE)
  540. SBI(fanState, pgm_read_byte(&fanBit[5]));
  541. #endif
  542. uint8_t fanDone = 0;
  543. for (uint8_t f = 0; f < COUNT(fanPin); f++) {
  544. const pin_t pin =
  545. #ifdef ARDUINO
  546. pgm_read_byte(&fanPin[f])
  547. #else
  548. fanPin[f]
  549. #endif
  550. ;
  551. const uint8_t bit = pgm_read_byte(&fanBit[f]);
  552. if (pin >= 0 && !TEST(fanDone, bit)) {
  553. uint8_t newFanSpeed = TEST(fanState, bit) ? EXTRUDER_AUTO_FAN_SPEED : 0;
  554. #if ENABLED(AUTO_POWER_E_FANS)
  555. autofan_speed[f] = newFanSpeed;
  556. #endif
  557. // this idiom allows both digital and PWM fan outputs (see M42 handling).
  558. digitalWrite(pin, newFanSpeed);
  559. analogWrite(pin, newFanSpeed);
  560. SBI(fanDone, bit);
  561. }
  562. }
  563. }
  564. #endif // HAS_AUTO_FAN
  565. //
  566. // Temperature Error Handlers
  567. //
  568. void Temperature::_temp_error(const int8_t heater, PGM_P const serial_msg, PGM_P const lcd_msg) {
  569. static bool killed = false;
  570. if (IsRunning()) {
  571. SERIAL_ERROR_START();
  572. serialprintPGM(serial_msg);
  573. SERIAL_ECHOPGM(MSG_STOPPED_HEATER);
  574. if (heater >= 0) SERIAL_ECHOLN((int)heater); else SERIAL_ECHOLNPGM(MSG_HEATER_BED);
  575. }
  576. #if DISABLED(BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE)
  577. if (!killed) {
  578. Running = false;
  579. killed = true;
  580. kill(lcd_msg);
  581. }
  582. else
  583. disable_all_heaters(); // paranoia
  584. #endif
  585. }
  586. void Temperature::max_temp_error(const int8_t heater) {
  587. _temp_error(heater, PSTR(MSG_T_MAXTEMP), TEMP_ERR_PSTR(MSG_ERR_MAXTEMP, heater));
  588. }
  589. void Temperature::min_temp_error(const int8_t heater) {
  590. _temp_error(heater, PSTR(MSG_T_MINTEMP), TEMP_ERR_PSTR(MSG_ERR_MINTEMP, heater));
  591. }
  592. float Temperature::get_pid_output(const int8_t e) {
  593. #if HOTENDS == 1
  594. UNUSED(e);
  595. #define _HOTEND_TEST true
  596. #else
  597. #define _HOTEND_TEST (e == active_extruder)
  598. #endif
  599. float pid_output;
  600. #if ENABLED(PIDTEMP)
  601. #if DISABLED(PID_OPENLOOP)
  602. static hotend_pid_t work_pid[HOTENDS];
  603. static float temp_iState[HOTENDS] = { 0 },
  604. temp_dState[HOTENDS] = { 0 };
  605. static bool pid_reset[HOTENDS] = { false };
  606. float pid_error = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX];
  607. work_pid[HOTEND_INDEX].Kd = PID_K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + float(PID_K1) * work_pid[HOTEND_INDEX].Kd;
  608. temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX];
  609. #if HEATER_IDLE_HANDLER
  610. if (heater_idle_timeout_exceeded[HOTEND_INDEX]) {
  611. pid_output = 0;
  612. pid_reset[HOTEND_INDEX] = true;
  613. }
  614. else
  615. #endif
  616. if (pid_error > PID_FUNCTIONAL_RANGE) {
  617. pid_output = BANG_MAX;
  618. pid_reset[HOTEND_INDEX] = true;
  619. }
  620. else if (pid_error < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0
  621. #if HEATER_IDLE_HANDLER
  622. || heater_idle_timeout_exceeded[HOTEND_INDEX]
  623. #endif
  624. ) {
  625. pid_output = 0;
  626. pid_reset[HOTEND_INDEX] = true;
  627. }
  628. else {
  629. if (pid_reset[HOTEND_INDEX]) {
  630. temp_iState[HOTEND_INDEX] = 0.0;
  631. pid_reset[HOTEND_INDEX] = false;
  632. }
  633. temp_iState[HOTEND_INDEX] += pid_error;
  634. work_pid[HOTEND_INDEX].Kp = PID_PARAM(Kp, HOTEND_INDEX) * pid_error;
  635. work_pid[HOTEND_INDEX].Ki = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
  636. pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki - work_pid[HOTEND_INDEX].Kd;
  637. #if ENABLED(PID_EXTRUSION_SCALING)
  638. work_pid[HOTEND_INDEX].Kc = 0;
  639. if (_HOTEND_TEST) {
  640. const long e_position = stepper.position(E_AXIS);
  641. if (e_position > last_e_position) {
  642. lpq[lpq_ptr] = e_position - last_e_position;
  643. last_e_position = e_position;
  644. }
  645. else
  646. lpq[lpq_ptr] = 0;
  647. if (++lpq_ptr >= lpq_len) lpq_ptr = 0;
  648. work_pid[HOTEND_INDEX].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX);
  649. pid_output += work_pid[HOTEND_INDEX].Kc;
  650. }
  651. #endif // PID_EXTRUSION_SCALING
  652. if (pid_output > PID_MAX) {
  653. if (pid_error > 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
  654. pid_output = PID_MAX;
  655. }
  656. else if (pid_output < 0) {
  657. if (pid_error < 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
  658. pid_output = 0;
  659. }
  660. }
  661. #else // PID_OPENLOOP
  662. const float pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX);
  663. #endif // PID_OPENLOOP
  664. #if ENABLED(PID_DEBUG)
  665. SERIAL_ECHO_START();
  666. SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX);
  667. SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]);
  668. SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output);
  669. #if DISABLED(PID_OPENLOOP)
  670. SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, work_pid[HOTEND_INDEX].Kp);
  671. SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, work_pid[HOTEND_INDEX].Ki);
  672. SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, work_pid[HOTEND_INDEX].Kd);
  673. #if ENABLED(PID_EXTRUSION_SCALING)
  674. SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, work_pid[HOTEND_INDEX].Kc);
  675. #endif
  676. #endif
  677. SERIAL_EOL();
  678. #endif // PID_DEBUG
  679. #else /* PID off */
  680. #if HEATER_IDLE_HANDLER
  681. if (heater_idle_timeout_exceeded[HOTEND_INDEX])
  682. pid_output = 0;
  683. else
  684. #endif
  685. pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0;
  686. #endif
  687. return pid_output;
  688. }
  689. #if ENABLED(PIDTEMPBED)
  690. float Temperature::get_pid_output_bed() {
  691. #if DISABLED(PID_OPENLOOP)
  692. static PID_t work_pid = { 0 };
  693. static float temp_iState = 0, temp_dState = 0;
  694. float pid_error = target_temperature_bed - current_temperature_bed;
  695. temp_iState += pid_error;
  696. work_pid.Kp = bed_pid.Kp * pid_error;
  697. work_pid.Ki = bed_pid.Ki * temp_iState;
  698. work_pid.Kd = PID_K2 * bed_pid.Kd * (current_temperature_bed - temp_dState) + PID_K1 * work_pid.Kd;
  699. temp_dState = current_temperature_bed;
  700. float pid_output = work_pid.Kp + work_pid.Ki - work_pid.Kd;
  701. if (pid_output > MAX_BED_POWER) {
  702. if (pid_error > 0) temp_iState -= pid_error; // conditional un-integration
  703. pid_output = MAX_BED_POWER;
  704. }
  705. else if (pid_output < 0) {
  706. if (pid_error < 0) temp_iState -= pid_error; // conditional un-integration
  707. pid_output = 0;
  708. }
  709. #else // PID_OPENLOOP
  710. const float pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
  711. #endif // PID_OPENLOOP
  712. #if ENABLED(PID_BED_DEBUG)
  713. SERIAL_ECHO_START();
  714. SERIAL_ECHOPAIR(" PID_BED_DEBUG : Input ", current_temperature_bed);
  715. SERIAL_ECHOPAIR(" Output ", pid_output);
  716. #if DISABLED(PID_OPENLOOP)
  717. SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, work_pid.Kp);
  718. SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, work_pid.Ki);
  719. SERIAL_ECHOLNPAIR(MSG_PID_DEBUG_DTERM, work_pid.Kd);
  720. #endif
  721. #endif
  722. return pid_output;
  723. }
  724. #endif // PIDTEMPBED
  725. /**
  726. * Manage heating activities for extruder hot-ends and a heated bed
  727. * - Acquire updated temperature readings
  728. * - Also resets the watchdog timer
  729. * - Invoke thermal runaway protection
  730. * - Manage extruder auto-fan
  731. * - Apply filament width to the extrusion rate (may move)
  732. * - Update the heated bed PID output value
  733. */
  734. void Temperature::manage_heater() {
  735. #if EARLY_WATCHDOG
  736. // If thermal manager is still not running, make sure to at least reset the watchdog!
  737. if (!inited) {
  738. watchdog_reset();
  739. return;
  740. }
  741. #endif
  742. #if ENABLED(PROBING_HEATERS_OFF) && ENABLED(BED_LIMIT_SWITCHING)
  743. static bool last_pause_state;
  744. #endif
  745. #if ENABLED(EMERGENCY_PARSER)
  746. if (emergency_parser.killed_by_M112) kill();
  747. #endif
  748. if (!temp_meas_ready) return;
  749. updateTemperaturesFromRawValues(); // also resets the watchdog
  750. #if ENABLED(HEATER_0_USES_MAX6675)
  751. if (current_temperature[0] > MIN(HEATER_0_MAXTEMP, HEATER_0_MAX6675_TMAX - 1.0)) max_temp_error(0);
  752. if (current_temperature[0] < MAX(HEATER_0_MINTEMP, HEATER_0_MAX6675_TMIN + .01)) min_temp_error(0);
  753. #endif
  754. #if ENABLED(HEATER_1_USES_MAX6675)
  755. if (current_temperature[1] > MIN(HEATER_1_MAXTEMP, HEATER_1_MAX6675_TMAX - 1.0)) max_temp_error(1);
  756. if (current_temperature[1] < MAX(HEATER_1_MINTEMP, HEATER_1_MAX6675_TMIN + .01)) min_temp_error(1);
  757. #endif
  758. #if WATCH_HOTENDS || WATCH_THE_BED || DISABLED(PIDTEMPBED) || HAS_AUTO_FAN || HEATER_IDLE_HANDLER
  759. millis_t ms = millis();
  760. #endif
  761. HOTEND_LOOP() {
  762. #if HEATER_IDLE_HANDLER
  763. if (!heater_idle_timeout_exceeded[e] && heater_idle_timeout_ms[e] && ELAPSED(ms, heater_idle_timeout_ms[e]))
  764. heater_idle_timeout_exceeded[e] = true;
  765. #endif
  766. #if ENABLED(THERMAL_PROTECTION_HOTENDS)
  767. // Check for thermal runaway
  768. thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
  769. #endif
  770. soft_pwm_amount[e] = (current_temperature[e] > minttemp[e] || is_preheating(e)) && current_temperature[e] < maxttemp[e] ? (int)get_pid_output(e) >> 1 : 0;
  771. #if WATCH_HOTENDS
  772. // Make sure temperature is increasing
  773. if (watch_heater_next_ms[e] && ELAPSED(ms, watch_heater_next_ms[e])) { // Time to check this extruder?
  774. if (degHotend(e) < watch_target_temp[e]) // Failed to increase enough?
  775. _temp_error(e, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, e));
  776. else // Start again if the target is still far off
  777. start_watching_heater(e);
  778. }
  779. #endif
  780. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  781. // Make sure measured temperatures are close together
  782. if (ABS(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF)
  783. _temp_error(0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP));
  784. #endif
  785. } // HOTEND_LOOP
  786. #if HAS_AUTO_FAN
  787. if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently
  788. checkExtruderAutoFans();
  789. next_auto_fan_check_ms = ms + 2500UL;
  790. }
  791. #endif
  792. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  793. /**
  794. * Filament Width Sensor dynamically sets the volumetric multiplier
  795. * based on a delayed measurement of the filament diameter.
  796. */
  797. if (filament_sensor) {
  798. meas_shift_index = filwidth_delay_index[0] - meas_delay_cm;
  799. if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
  800. meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
  801. planner.calculate_volumetric_for_width_sensor(measurement_delay[meas_shift_index]);
  802. }
  803. #endif // FILAMENT_WIDTH_SENSOR
  804. #if HAS_HEATED_BED
  805. #if WATCH_THE_BED
  806. // Make sure temperature is increasing
  807. if (watch_bed_next_ms && ELAPSED(ms, watch_bed_next_ms)) { // Time to check the bed?
  808. if (degBed() < watch_target_bed_temp) // Failed to increase enough?
  809. _temp_error(-1, PSTR(MSG_T_HEATING_FAILED), TEMP_ERR_PSTR(MSG_HEATING_FAILED_LCD, -1));
  810. else // Start again if the target is still far off
  811. start_watching_bed();
  812. }
  813. #endif // WATCH_THE_BED
  814. #if DISABLED(PIDTEMPBED)
  815. if (PENDING(ms, next_bed_check_ms)
  816. #if ENABLED(PROBING_HEATERS_OFF) && ENABLED(BED_LIMIT_SWITCHING)
  817. && paused == last_pause_state
  818. #endif
  819. ) return;
  820. next_bed_check_ms = ms + BED_CHECK_INTERVAL;
  821. #if ENABLED(PROBING_HEATERS_OFF) && ENABLED(BED_LIMIT_SWITCHING)
  822. last_pause_state = paused;
  823. #endif
  824. #endif
  825. #if HEATER_IDLE_HANDLER
  826. if (!bed_idle_timeout_exceeded && bed_idle_timeout_ms && ELAPSED(ms, bed_idle_timeout_ms))
  827. bed_idle_timeout_exceeded = true;
  828. #endif
  829. #if HAS_THERMALLY_PROTECTED_BED
  830. thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
  831. #endif
  832. #if HEATER_IDLE_HANDLER
  833. if (bed_idle_timeout_exceeded) {
  834. soft_pwm_amount_bed = 0;
  835. #if DISABLED(PIDTEMPBED)
  836. WRITE_HEATER_BED(LOW);
  837. #endif
  838. }
  839. else
  840. #endif
  841. {
  842. #if ENABLED(PIDTEMPBED)
  843. soft_pwm_amount_bed = WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP) ? (int)get_pid_output_bed() >> 1 : 0;
  844. #else
  845. // Check if temperature is within the correct band
  846. if (WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP)) {
  847. #if ENABLED(BED_LIMIT_SWITCHING)
  848. if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS)
  849. soft_pwm_amount_bed = 0;
  850. else if (current_temperature_bed <= target_temperature_bed - (BED_HYSTERESIS))
  851. soft_pwm_amount_bed = MAX_BED_POWER >> 1;
  852. #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING
  853. soft_pwm_amount_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
  854. #endif
  855. }
  856. else {
  857. soft_pwm_amount_bed = 0;
  858. WRITE_HEATER_BED(LOW);
  859. }
  860. #endif
  861. }
  862. #endif // HAS_HEATED_BED
  863. }
  864. #define TEMP_AD595(RAW) ((RAW) * 5.0 * 100.0 / 1024.0 / (OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET)
  865. #define TEMP_AD8495(RAW) ((RAW) * 6.6 * 100.0 / 1024.0 / (OVERSAMPLENR) * (TEMP_SENSOR_AD8495_GAIN) + TEMP_SENSOR_AD8495_OFFSET)
  866. /**
  867. * Bisect search for the range of the 'raw' value, then interpolate
  868. * proportionally between the under and over values.
  869. */
  870. #define SCAN_THERMISTOR_TABLE(TBL,LEN) do{ \
  871. uint8_t l = 0, r = LEN, m; \
  872. for (;;) { \
  873. m = (l + r) >> 1; \
  874. if (m == l || m == r) return (short)pgm_read_word(&TBL[LEN-1][1]); \
  875. short v00 = pgm_read_word(&TBL[m-1][0]), \
  876. v10 = pgm_read_word(&TBL[m-0][0]); \
  877. if (raw < v00) r = m; \
  878. else if (raw > v10) l = m; \
  879. else { \
  880. const short v01 = (short)pgm_read_word(&TBL[m-1][1]), \
  881. v11 = (short)pgm_read_word(&TBL[m-0][1]); \
  882. return v01 + (raw - v00) * float(v11 - v01) / float(v10 - v00); \
  883. } \
  884. } \
  885. }while(0)
  886. // Derived from RepRap FiveD extruder::getTemperature()
  887. // For hot end temperature measurement.
  888. float Temperature::analog_to_celsius_hotend(const int raw, const uint8_t e) {
  889. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  890. if (e > HOTENDS)
  891. #else
  892. if (e >= HOTENDS)
  893. #endif
  894. {
  895. SERIAL_ERROR_START();
  896. SERIAL_ECHO((int)e);
  897. SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER_NUM);
  898. kill();
  899. return 0.0;
  900. }
  901. switch (e) {
  902. case 0:
  903. #if ENABLED(HEATER_0_USES_MAX6675)
  904. return raw * 0.25;
  905. #elif ENABLED(HEATER_0_USES_AD595)
  906. return TEMP_AD595(raw);
  907. #elif ENABLED(HEATER_0_USES_AD8495)
  908. return TEMP_AD8495(raw);
  909. #else
  910. break;
  911. #endif
  912. case 1:
  913. #if ENABLED(HEATER_1_USES_MAX6675)
  914. return raw * 0.25;
  915. #elif ENABLED(HEATER_1_USES_AD595)
  916. return TEMP_AD595(raw);
  917. #elif ENABLED(HEATER_1_USES_AD8495)
  918. return TEMP_AD8495(raw);
  919. #else
  920. break;
  921. #endif
  922. case 2:
  923. #if ENABLED(HEATER_2_USES_AD595)
  924. return TEMP_AD595(raw);
  925. #elif ENABLED(HEATER_2_USES_AD8495)
  926. return TEMP_AD8495(raw);
  927. #else
  928. break;
  929. #endif
  930. case 3:
  931. #if ENABLED(HEATER_3_USES_AD595)
  932. return TEMP_AD595(raw);
  933. #elif ENABLED(HEATER_3_USES_AD8495)
  934. return TEMP_AD8495(raw);
  935. #else
  936. break;
  937. #endif
  938. case 4:
  939. #if ENABLED(HEATER_4_USES_AD595)
  940. return TEMP_AD595(raw);
  941. #elif ENABLED(HEATER_4_USES_AD8495)
  942. return TEMP_AD8495(raw);
  943. #else
  944. break;
  945. #endif
  946. default: break;
  947. }
  948. #if HOTEND_USES_THERMISTOR
  949. // Thermistor with conversion table?
  950. const short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]);
  951. SCAN_THERMISTOR_TABLE((*tt), heater_ttbllen_map[e]);
  952. #endif
  953. return 0;
  954. }
  955. #if HAS_HEATED_BED
  956. // Derived from RepRap FiveD extruder::getTemperature()
  957. // For bed temperature measurement.
  958. float Temperature::analog_to_celsius_bed(const int raw) {
  959. #if ENABLED(HEATER_BED_USES_THERMISTOR)
  960. SCAN_THERMISTOR_TABLE(BEDTEMPTABLE, BEDTEMPTABLE_LEN);
  961. #elif ENABLED(HEATER_BED_USES_AD595)
  962. return TEMP_AD595(raw);
  963. #elif ENABLED(HEATER_BED_USES_AD8495)
  964. return TEMP_AD8495(raw);
  965. #else
  966. return 0;
  967. #endif
  968. }
  969. #endif // HAS_HEATED_BED
  970. #if HAS_TEMP_CHAMBER
  971. // Derived from RepRap FiveD extruder::getTemperature()
  972. // For chamber temperature measurement.
  973. float Temperature::analog_to_celsiusChamber(const int raw) {
  974. #if ENABLED(HEATER_CHAMBER_USES_THERMISTOR)
  975. SCAN_THERMISTOR_TABLE(CHAMBERTEMPTABLE, CHAMBERTEMPTABLE_LEN);
  976. #elif ENABLED(HEATER_CHAMBER_USES_AD595)
  977. return TEMP_AD595(raw);
  978. #elif ENABLED(HEATER_CHAMBER_USES_AD8495)
  979. return TEMP_AD8495(raw);
  980. #else
  981. return 0;
  982. #endif
  983. }
  984. #endif // HAS_TEMP_CHAMBER
  985. /**
  986. * Get the raw values into the actual temperatures.
  987. * The raw values are created in interrupt context,
  988. * and this function is called from normal context
  989. * as it would block the stepper routine.
  990. */
  991. void Temperature::updateTemperaturesFromRawValues() {
  992. #if ENABLED(HEATER_0_USES_MAX6675)
  993. current_temperature_raw[0] = READ_MAX6675(0);
  994. #endif
  995. #if ENABLED(HEATER_1_USES_MAX6675)
  996. current_temperature_raw[1] = READ_MAX6675(1);
  997. #endif
  998. HOTEND_LOOP() current_temperature[e] = analog_to_celsius_hotend(current_temperature_raw[e], e);
  999. #if HAS_HEATED_BED
  1000. current_temperature_bed = analog_to_celsius_bed(current_temperature_bed_raw);
  1001. #endif
  1002. #if HAS_TEMP_CHAMBER
  1003. current_temperature_chamber = analog_to_celsiusChamber(current_temperature_chamber_raw);
  1004. #endif
  1005. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  1006. redundant_temperature = analog_to_celsius_hotend(redundant_temperature_raw, 1);
  1007. #endif
  1008. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  1009. filament_width_meas = analog_to_mm_fil_width();
  1010. #endif
  1011. #if ENABLED(USE_WATCHDOG)
  1012. // Reset the watchdog after we know we have a temperature measurement.
  1013. watchdog_reset();
  1014. #endif
  1015. temp_meas_ready = false;
  1016. }
  1017. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  1018. // Convert raw Filament Width to millimeters
  1019. float Temperature::analog_to_mm_fil_width() {
  1020. return current_raw_filwidth * 5.0f * (1.0f / 16383.0f);
  1021. }
  1022. /**
  1023. * Convert Filament Width (mm) to a simple ratio
  1024. * and reduce to an 8 bit value.
  1025. *
  1026. * A nominal width of 1.75 and measured width of 1.73
  1027. * gives (100 * 1.75 / 1.73) for a ratio of 101 and
  1028. * a return value of 1.
  1029. */
  1030. int8_t Temperature::widthFil_to_size_ratio() {
  1031. if (ABS(filament_width_nominal - filament_width_meas) <= FILWIDTH_ERROR_MARGIN)
  1032. return int(100.0f * filament_width_nominal / filament_width_meas) - 100;
  1033. return 0;
  1034. }
  1035. #endif
  1036. #if MAX6675_SEPARATE_SPI
  1037. SPIclass<MAX6675_DO_PIN, MOSI_PIN, MAX6675_SCK_PIN> max6675_spi;
  1038. #endif
  1039. /**
  1040. * Initialize the temperature manager
  1041. * The manager is implemented by periodic calls to manage_heater()
  1042. */
  1043. void Temperature::init() {
  1044. #if EARLY_WATCHDOG
  1045. // Flag that the thermalManager should be running
  1046. if (inited) return;
  1047. inited = true;
  1048. #endif
  1049. #if MB(RUMBA) && ( \
  1050. ENABLED(HEATER_0_USES_AD595) || ENABLED(HEATER_1_USES_AD595) || ENABLED(HEATER_2_USES_AD595) || ENABLED(HEATER_3_USES_AD595) || ENABLED(HEATER_4_USES_AD595) || ENABLED(HEATER_BED_USES_AD595) || ENABLED(HEATER_CHAMBER_USES_AD595) \
  1051. || ENABLED(HEATER_0_USES_AD8495) || ENABLED(HEATER_1_USES_AD8495) || ENABLED(HEATER_2_USES_AD8495) || ENABLED(HEATER_3_USES_AD8495) || ENABLED(HEATER_4_USES_AD8495) || ENABLED(HEATER_BED_USES_AD8495) || ENABLED(HEATER_CHAMBER_USES_AD8495))
  1052. // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
  1053. MCUCR = _BV(JTD);
  1054. MCUCR = _BV(JTD);
  1055. #endif
  1056. // Finish init of mult hotend arrays
  1057. HOTEND_LOOP() maxttemp[e] = maxttemp[0];
  1058. #if ENABLED(PIDTEMP) && ENABLED(PID_EXTRUSION_SCALING)
  1059. last_e_position = 0;
  1060. #endif
  1061. #if HAS_HEATER_0
  1062. OUT_WRITE(HEATER_0_PIN, HEATER_0_INVERTING);
  1063. #endif
  1064. #if HAS_HEATER_1
  1065. OUT_WRITE(HEATER_1_PIN, HEATER_1_INVERTING);
  1066. #endif
  1067. #if HAS_HEATER_2
  1068. OUT_WRITE(HEATER_2_PIN, HEATER_2_INVERTING);
  1069. #endif
  1070. #if HAS_HEATER_3
  1071. OUT_WRITE(HEATER_3_PIN, HEATER_3_INVERTING);
  1072. #endif
  1073. #if HAS_HEATER_4
  1074. OUT_WRITE(HEATER_4_PIN, HEATER_4_INVERTING);
  1075. #endif
  1076. #if HAS_HEATED_BED
  1077. OUT_WRITE(HEATER_BED_PIN, HEATER_BED_INVERTING);
  1078. #endif
  1079. #if HAS_FAN0
  1080. SET_OUTPUT(FAN_PIN);
  1081. #if ENABLED(FAST_PWM_FAN)
  1082. setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1083. #endif
  1084. #endif
  1085. #if HAS_FAN1
  1086. SET_OUTPUT(FAN1_PIN);
  1087. #if ENABLED(FAST_PWM_FAN)
  1088. setPwmFrequency(FAN1_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1089. #endif
  1090. #endif
  1091. #if HAS_FAN2
  1092. SET_OUTPUT(FAN2_PIN);
  1093. #if ENABLED(FAST_PWM_FAN)
  1094. setPwmFrequency(FAN2_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1095. #endif
  1096. #endif
  1097. #if ENABLED(USE_CONTROLLER_FAN)
  1098. SET_OUTPUT(CONTROLLER_FAN_PIN);
  1099. #if ENABLED(FAST_PWM_FAN)
  1100. setPwmFrequency(CONTROLLER_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1101. #endif
  1102. #endif
  1103. #if MAX6675_SEPARATE_SPI
  1104. OUT_WRITE(SCK_PIN, LOW);
  1105. OUT_WRITE(MOSI_PIN, HIGH);
  1106. SET_INPUT_PULLUP(MISO_PIN);
  1107. max6675_spi.init();
  1108. OUT_WRITE(SS_PIN, HIGH);
  1109. OUT_WRITE(MAX6675_SS_PIN, HIGH);
  1110. #endif
  1111. #if ENABLED(HEATER_1_USES_MAX6675)
  1112. OUT_WRITE(MAX6675_SS2_PIN, HIGH);
  1113. #endif
  1114. HAL_adc_init();
  1115. #if HAS_TEMP_ADC_0
  1116. HAL_ANALOG_SELECT(TEMP_0_PIN);
  1117. #endif
  1118. #if HAS_TEMP_ADC_1
  1119. HAL_ANALOG_SELECT(TEMP_1_PIN);
  1120. #endif
  1121. #if HAS_TEMP_ADC_2
  1122. HAL_ANALOG_SELECT(TEMP_2_PIN);
  1123. #endif
  1124. #if HAS_TEMP_ADC_3
  1125. HAL_ANALOG_SELECT(TEMP_3_PIN);
  1126. #endif
  1127. #if HAS_TEMP_ADC_4
  1128. HAL_ANALOG_SELECT(TEMP_4_PIN);
  1129. #endif
  1130. #if HAS_TEMP_ADC_5
  1131. HAL_ANALOG_SELECT(TEMP_5_PIN);
  1132. #endif
  1133. #if HAS_HEATED_BED
  1134. HAL_ANALOG_SELECT(TEMP_BED_PIN);
  1135. #endif
  1136. #if HAS_TEMP_CHAMBER
  1137. HAL_ANALOG_SELECT(TEMP_CHAMBER_PIN);
  1138. #endif
  1139. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  1140. HAL_ANALOG_SELECT(FILWIDTH_PIN);
  1141. #endif
  1142. HAL_timer_start(TEMP_TIMER_NUM, TEMP_TIMER_FREQUENCY);
  1143. ENABLE_TEMPERATURE_INTERRUPT();
  1144. #if HAS_AUTO_FAN_0
  1145. #if E0_AUTO_FAN_PIN == FAN1_PIN
  1146. SET_OUTPUT(E0_AUTO_FAN_PIN);
  1147. #if ENABLED(FAST_PWM_FAN)
  1148. setPwmFrequency(E0_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1149. #endif
  1150. #else
  1151. SET_OUTPUT(E0_AUTO_FAN_PIN);
  1152. #endif
  1153. #endif
  1154. #if HAS_AUTO_FAN_1 && !AUTO_1_IS_0
  1155. #if E1_AUTO_FAN_PIN == FAN1_PIN
  1156. SET_OUTPUT(E1_AUTO_FAN_PIN);
  1157. #if ENABLED(FAST_PWM_FAN)
  1158. setPwmFrequency(E1_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1159. #endif
  1160. #else
  1161. SET_OUTPUT(E1_AUTO_FAN_PIN);
  1162. #endif
  1163. #endif
  1164. #if HAS_AUTO_FAN_2 && !(AUTO_2_IS_0 || AUTO_2_IS_1)
  1165. #if E2_AUTO_FAN_PIN == FAN1_PIN
  1166. SET_OUTPUT(E2_AUTO_FAN_PIN);
  1167. #if ENABLED(FAST_PWM_FAN)
  1168. setPwmFrequency(E2_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1169. #endif
  1170. #else
  1171. SET_OUTPUT(E2_AUTO_FAN_PIN);
  1172. #endif
  1173. #endif
  1174. #if HAS_AUTO_FAN_3 && !(AUTO_3_IS_0 || AUTO_3_IS_1 || AUTO_3_IS_2)
  1175. #if E3_AUTO_FAN_PIN == FAN1_PIN
  1176. SET_OUTPUT(E3_AUTO_FAN_PIN);
  1177. #if ENABLED(FAST_PWM_FAN)
  1178. setPwmFrequency(E3_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1179. #endif
  1180. #else
  1181. SET_OUTPUT(E3_AUTO_FAN_PIN);
  1182. #endif
  1183. #endif
  1184. #if HAS_AUTO_FAN_4 && !(AUTO_4_IS_0 || AUTO_4_IS_1 || AUTO_4_IS_2 || AUTO_4_IS_3)
  1185. #if E4_AUTO_FAN_PIN == FAN1_PIN
  1186. SET_OUTPUT(E4_AUTO_FAN_PIN);
  1187. #if ENABLED(FAST_PWM_FAN)
  1188. setPwmFrequency(E4_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1189. #endif
  1190. #else
  1191. SET_OUTPUT(E4_AUTO_FAN_PIN);
  1192. #endif
  1193. #endif
  1194. #if HAS_AUTO_FAN_5 && !(AUTO_5_IS_0 || AUTO_5_IS_1 || AUTO_5_IS_2 || AUTO_5_IS_3 || AUTO_5_IS_4)
  1195. #if E5_AUTO_FAN_PIN == FAN1_PIN
  1196. SET_OUTPUT(E5_AUTO_FAN_PIN);
  1197. #if ENABLED(FAST_PWM_FAN)
  1198. setPwmFrequency(E5_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1199. #endif
  1200. #else
  1201. SET_OUTPUT(E5_AUTO_FAN_PIN);
  1202. #endif
  1203. #endif
  1204. #if HAS_AUTO_CHAMBER_FAN && !(AUTO_CHAMBER_IS_0 || AUTO_CHAMBER_IS_1 || AUTO_CHAMBER_IS_2 || AUTO_CHAMBER_IS_3 || AUTO_CHAMBER_IS_4 || AUTO_CHAMBER_IS_5)
  1205. #if CHAMBER_AUTO_FAN_PIN == FAN1_PIN
  1206. SET_OUTPUT(CHAMBER_AUTO_FAN_PIN);
  1207. #if ENABLED(FAST_PWM_FAN)
  1208. setPwmFrequency(CHAMBER_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  1209. #endif
  1210. #else
  1211. SET_OUTPUT(CHAMBER_AUTO_FAN_PIN);
  1212. #endif
  1213. #endif
  1214. // Wait for temperature measurement to settle
  1215. delay(250);
  1216. #define TEMP_MIN_ROUTINE(NR) \
  1217. minttemp[NR] = HEATER_ ##NR## _MINTEMP; \
  1218. while (analog_to_celsius_hotend(minttemp_raw[NR], NR) < HEATER_ ##NR## _MINTEMP) { \
  1219. if (HEATER_ ##NR## _RAW_LO_TEMP < HEATER_ ##NR## _RAW_HI_TEMP) \
  1220. minttemp_raw[NR] += OVERSAMPLENR; \
  1221. else \
  1222. minttemp_raw[NR] -= OVERSAMPLENR; \
  1223. }
  1224. #define TEMP_MAX_ROUTINE(NR) \
  1225. maxttemp[NR] = HEATER_ ##NR## _MAXTEMP; \
  1226. while (analog_to_celsius_hotend(maxttemp_raw[NR], NR) > HEATER_ ##NR## _MAXTEMP) { \
  1227. if (HEATER_ ##NR## _RAW_LO_TEMP < HEATER_ ##NR## _RAW_HI_TEMP) \
  1228. maxttemp_raw[NR] -= OVERSAMPLENR; \
  1229. else \
  1230. maxttemp_raw[NR] += OVERSAMPLENR; \
  1231. }
  1232. #ifdef HEATER_0_MINTEMP
  1233. TEMP_MIN_ROUTINE(0);
  1234. #endif
  1235. #ifdef HEATER_0_MAXTEMP
  1236. TEMP_MAX_ROUTINE(0);
  1237. #endif
  1238. #if HOTENDS > 1
  1239. #ifdef HEATER_1_MINTEMP
  1240. TEMP_MIN_ROUTINE(1);
  1241. #endif
  1242. #ifdef HEATER_1_MAXTEMP
  1243. TEMP_MAX_ROUTINE(1);
  1244. #endif
  1245. #if HOTENDS > 2
  1246. #ifdef HEATER_2_MINTEMP
  1247. TEMP_MIN_ROUTINE(2);
  1248. #endif
  1249. #ifdef HEATER_2_MAXTEMP
  1250. TEMP_MAX_ROUTINE(2);
  1251. #endif
  1252. #if HOTENDS > 3
  1253. #ifdef HEATER_3_MINTEMP
  1254. TEMP_MIN_ROUTINE(3);
  1255. #endif
  1256. #ifdef HEATER_3_MAXTEMP
  1257. TEMP_MAX_ROUTINE(3);
  1258. #endif
  1259. #if HOTENDS > 4
  1260. #ifdef HEATER_4_MINTEMP
  1261. TEMP_MIN_ROUTINE(4);
  1262. #endif
  1263. #ifdef HEATER_4_MAXTEMP
  1264. TEMP_MAX_ROUTINE(4);
  1265. #endif
  1266. #if HOTENDS > 5
  1267. #ifdef HEATER_5_MINTEMP
  1268. TEMP_MIN_ROUTINE(5);
  1269. #endif
  1270. #ifdef HEATER_5_MAXTEMP
  1271. TEMP_MAX_ROUTINE(5);
  1272. #endif
  1273. #endif // HOTENDS > 5
  1274. #endif // HOTENDS > 4
  1275. #endif // HOTENDS > 3
  1276. #endif // HOTENDS > 2
  1277. #endif // HOTENDS > 1
  1278. #if HAS_HEATED_BED
  1279. #ifdef BED_MINTEMP
  1280. while (analog_to_celsius_bed(bed_minttemp_raw) < BED_MINTEMP) {
  1281. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  1282. bed_minttemp_raw += OVERSAMPLENR;
  1283. #else
  1284. bed_minttemp_raw -= OVERSAMPLENR;
  1285. #endif
  1286. }
  1287. #endif // BED_MINTEMP
  1288. #ifdef BED_MAXTEMP
  1289. while (analog_to_celsius_bed(bed_maxttemp_raw) > BED_MAXTEMP) {
  1290. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  1291. bed_maxttemp_raw -= OVERSAMPLENR;
  1292. #else
  1293. bed_maxttemp_raw += OVERSAMPLENR;
  1294. #endif
  1295. }
  1296. #endif // BED_MAXTEMP
  1297. #endif // HAS_HEATED_BED
  1298. #if ENABLED(PROBING_HEATERS_OFF)
  1299. paused = false;
  1300. #endif
  1301. }
  1302. #if ENABLED(FAST_PWM_FAN)
  1303. void Temperature::setPwmFrequency(const pin_t pin, int val) {
  1304. #if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
  1305. val &= 0x07;
  1306. switch (digitalPinToTimer(pin)) {
  1307. #ifdef TCCR0A
  1308. #if !AVR_AT90USB1286_FAMILY
  1309. case TIMER0A:
  1310. #endif
  1311. case TIMER0B: //_SET_CS(0, val);
  1312. break;
  1313. #endif
  1314. #ifdef TCCR1A
  1315. case TIMER1A: case TIMER1B: //_SET_CS(1, val);
  1316. break;
  1317. #endif
  1318. #if defined(TCCR2) || defined(TCCR2A)
  1319. #ifdef TCCR2
  1320. case TIMER2:
  1321. #endif
  1322. #ifdef TCCR2A
  1323. case TIMER2A: case TIMER2B:
  1324. #endif
  1325. _SET_CS(2, val); break;
  1326. #endif
  1327. #ifdef TCCR3A
  1328. case TIMER3A: case TIMER3B: case TIMER3C: _SET_CS(3, val); break;
  1329. #endif
  1330. #ifdef TCCR4A
  1331. case TIMER4A: case TIMER4B: case TIMER4C: _SET_CS(4, val); break;
  1332. #endif
  1333. #ifdef TCCR5A
  1334. case TIMER5A: case TIMER5B: case TIMER5C: _SET_CS(5, val); break;
  1335. #endif
  1336. }
  1337. #endif
  1338. }
  1339. #endif // FAST_PWM_FAN
  1340. #if WATCH_HOTENDS
  1341. /**
  1342. * Start Heating Sanity Check for hotends that are below
  1343. * their target temperature by a configurable margin.
  1344. * This is called when the temperature is set. (M104, M109)
  1345. */
  1346. void Temperature::start_watching_heater(const uint8_t e) {
  1347. #if HOTENDS == 1
  1348. UNUSED(e);
  1349. #endif
  1350. if (degTargetHotend(HOTEND_INDEX) && degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
  1351. watch_target_temp[HOTEND_INDEX] = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE;
  1352. watch_heater_next_ms[HOTEND_INDEX] = millis() + (WATCH_TEMP_PERIOD) * 1000UL;
  1353. }
  1354. else
  1355. watch_heater_next_ms[HOTEND_INDEX] = 0;
  1356. }
  1357. #endif
  1358. #if WATCH_THE_BED
  1359. /**
  1360. * Start Heating Sanity Check for hotends that are below
  1361. * their target temperature by a configurable margin.
  1362. * This is called when the temperature is set. (M140, M190)
  1363. */
  1364. void Temperature::start_watching_bed() {
  1365. if (degTargetBed() && degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) {
  1366. watch_target_bed_temp = degBed() + WATCH_BED_TEMP_INCREASE;
  1367. watch_bed_next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL;
  1368. }
  1369. else
  1370. watch_bed_next_ms = 0;
  1371. }
  1372. #endif
  1373. #if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED
  1374. #if ENABLED(THERMAL_PROTECTION_HOTENDS)
  1375. Temperature::TRState Temperature::thermal_runaway_state_machine[HOTENDS] = { TRInactive };
  1376. millis_t Temperature::thermal_runaway_timer[HOTENDS] = { 0 };
  1377. #endif
  1378. #if HAS_THERMALLY_PROTECTED_BED
  1379. Temperature::TRState Temperature::thermal_runaway_bed_state_machine = TRInactive;
  1380. millis_t Temperature::thermal_runaway_bed_timer;
  1381. #endif
  1382. void Temperature::thermal_runaway_protection(Temperature::TRState * const state, millis_t * const timer, const float &current, const float &target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) {
  1383. static float tr_target_temperature[HOTENDS + 1] = { 0.0 };
  1384. /**
  1385. SERIAL_ECHO_START();
  1386. SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: ");
  1387. if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id);
  1388. SERIAL_ECHOPAIR(" ; State:", *state);
  1389. SERIAL_ECHOPAIR(" ; Timer:", *timer);
  1390. SERIAL_ECHOPAIR(" ; Temperature:", current);
  1391. SERIAL_ECHOPAIR(" ; Target Temp:", target);
  1392. if (heater_id >= 0)
  1393. SERIAL_ECHOPAIR(" ; Idle Timeout:", heater_idle_timeout_exceeded[heater_id]);
  1394. else
  1395. SERIAL_ECHOPAIR(" ; Idle Timeout:", bed_idle_timeout_exceeded);
  1396. SERIAL_EOL();
  1397. */
  1398. const int heater_index = heater_id >= 0 ? heater_id : HOTENDS;
  1399. #if HEATER_IDLE_HANDLER
  1400. // If the heater idle timeout expires, restart
  1401. if ((heater_id >= 0 && heater_idle_timeout_exceeded[heater_id])
  1402. #if HAS_HEATED_BED
  1403. || (heater_id < 0 && bed_idle_timeout_exceeded)
  1404. #endif
  1405. ) {
  1406. *state = TRInactive;
  1407. tr_target_temperature[heater_index] = 0;
  1408. }
  1409. else
  1410. #endif
  1411. {
  1412. // If the target temperature changes, restart
  1413. if (tr_target_temperature[heater_index] != target) {
  1414. tr_target_temperature[heater_index] = target;
  1415. *state = target > 0 ? TRFirstHeating : TRInactive;
  1416. }
  1417. }
  1418. switch (*state) {
  1419. // Inactive state waits for a target temperature to be set
  1420. case TRInactive: break;
  1421. // When first heating, wait for the temperature to be reached then go to Stable state
  1422. case TRFirstHeating:
  1423. if (current < tr_target_temperature[heater_index]) break;
  1424. *state = TRStable;
  1425. // While the temperature is stable watch for a bad temperature
  1426. case TRStable:
  1427. #if ENABLED(ADAPTIVE_FAN_SLOWING)
  1428. if (adaptive_fan_slowing && heater_id >= 0) {
  1429. const int fan_index = MIN(heater_id, FAN_COUNT - 1);
  1430. if (fan_speed[fan_index] == 0 || current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.25f))
  1431. fan_speed_scaler[fan_index] = 128;
  1432. else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.3335f))
  1433. fan_speed_scaler[fan_index] = 96;
  1434. else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.5f))
  1435. fan_speed_scaler[fan_index] = 64;
  1436. else if (current >= tr_target_temperature[heater_id] - (hysteresis_degc * 0.8f))
  1437. fan_speed_scaler[fan_index] = 32;
  1438. else
  1439. fan_speed_scaler[fan_index] = 0;
  1440. }
  1441. #endif
  1442. if (current >= tr_target_temperature[heater_index] - hysteresis_degc) {
  1443. *timer = millis() + period_seconds * 1000UL;
  1444. break;
  1445. }
  1446. else if (PENDING(millis(), *timer)) break;
  1447. *state = TRRunaway;
  1448. case TRRunaway:
  1449. _temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), TEMP_ERR_PSTR(MSG_THERMAL_RUNAWAY, heater_id));
  1450. }
  1451. }
  1452. #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
  1453. void Temperature::disable_all_heaters() {
  1454. #if ENABLED(AUTOTEMP)
  1455. planner.autotemp_enabled = false;
  1456. #endif
  1457. HOTEND_LOOP() setTargetHotend(0, e);
  1458. #if HAS_HEATED_BED
  1459. setTargetBed(0);
  1460. #endif
  1461. // Unpause and reset everything
  1462. #if ENABLED(PROBING_HEATERS_OFF)
  1463. pause(false);
  1464. #endif
  1465. #define DISABLE_HEATER(NR) { \
  1466. setTargetHotend(0, NR); \
  1467. soft_pwm_amount[NR] = 0; \
  1468. WRITE_HEATER_ ##NR (LOW); \
  1469. }
  1470. #if HAS_TEMP_HOTEND
  1471. DISABLE_HEATER(0);
  1472. #if HOTENDS > 1
  1473. DISABLE_HEATER(1);
  1474. #if HOTENDS > 2
  1475. DISABLE_HEATER(2);
  1476. #if HOTENDS > 3
  1477. DISABLE_HEATER(3);
  1478. #if HOTENDS > 4
  1479. DISABLE_HEATER(4);
  1480. #if HOTENDS > 5
  1481. DISABLE_HEATER(5);
  1482. #endif // HOTENDS > 5
  1483. #endif // HOTENDS > 4
  1484. #endif // HOTENDS > 3
  1485. #endif // HOTENDS > 2
  1486. #endif // HOTENDS > 1
  1487. #endif
  1488. #if HAS_HEATED_BED
  1489. target_temperature_bed = 0;
  1490. soft_pwm_amount_bed = 0;
  1491. #if HAS_HEATED_BED
  1492. WRITE_HEATER_BED(LOW);
  1493. #endif
  1494. #endif
  1495. }
  1496. #if ENABLED(PROBING_HEATERS_OFF)
  1497. void Temperature::pause(const bool p) {
  1498. if (p != paused) {
  1499. paused = p;
  1500. if (p) {
  1501. HOTEND_LOOP() start_heater_idle_timer(e, 0); // timeout immediately
  1502. #if HAS_HEATED_BED
  1503. start_bed_idle_timer(0); // timeout immediately
  1504. #endif
  1505. }
  1506. else {
  1507. HOTEND_LOOP() reset_heater_idle_timer(e);
  1508. #if HAS_HEATED_BED
  1509. reset_bed_idle_timer();
  1510. #endif
  1511. }
  1512. }
  1513. }
  1514. #endif // PROBING_HEATERS_OFF
  1515. #if HAS_MAX6675
  1516. int Temperature::read_max6675(
  1517. #if COUNT_6675 > 1
  1518. const uint8_t hindex
  1519. #endif
  1520. ) {
  1521. #if COUNT_6675 == 1
  1522. constexpr uint8_t hindex = 0;
  1523. #else
  1524. // Needed to return the correct temp when this is called too soon
  1525. static uint16_t max6675_temp_previous[COUNT_6675] = { 0 };
  1526. #endif
  1527. #define MAX6675_HEAT_INTERVAL 250UL
  1528. #if ENABLED(MAX6675_IS_MAX31855)
  1529. static uint32_t max6675_temp = 2000;
  1530. #define MAX6675_ERROR_MASK 7
  1531. #define MAX6675_DISCARD_BITS 18
  1532. #define MAX6675_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64
  1533. #else
  1534. static uint16_t max6675_temp = 2000;
  1535. #define MAX6675_ERROR_MASK 4
  1536. #define MAX6675_DISCARD_BITS 3
  1537. #define MAX6675_SPEED_BITS 2 // (_BV(SPR0)) // clock ÷ 16
  1538. #endif
  1539. // Return last-read value between readings
  1540. static millis_t next_max6675_ms[COUNT_6675] = { 0 };
  1541. millis_t ms = millis();
  1542. if (PENDING(ms, next_max6675_ms[hindex]))
  1543. return int(
  1544. #if COUNT_6675 == 1
  1545. max6675_temp
  1546. #else
  1547. max6675_temp_previous[hindex] // Need to return the correct previous value
  1548. #endif
  1549. );
  1550. next_max6675_ms[hindex] = ms + MAX6675_HEAT_INTERVAL;
  1551. //
  1552. // TODO: spiBegin, spiRec and spiInit doesn't work when soft spi is used.
  1553. //
  1554. #if MAX6675_SEPARATE_SPI
  1555. spiBegin();
  1556. spiInit(MAX6675_SPEED_BITS);
  1557. #endif
  1558. #if COUNT_6675 > 1
  1559. #define WRITE_MAX6675(V) do{ switch (hindex) { case 1: WRITE(MAX6675_SS2_PIN, V); break; default: WRITE(MAX6675_SS_PIN, V); } }while(0)
  1560. #elif ENABLED(HEATER_1_USES_MAX6675)
  1561. #define WRITE_MAX6675(V) WRITE(MAX6675_SS2_PIN, V)
  1562. #else
  1563. #define WRITE_MAX6675(V) WRITE(MAX6675_SS_PIN, V)
  1564. #endif
  1565. WRITE_MAX6675(LOW); // enable TT_MAX6675
  1566. DELAY_NS(100); // Ensure 100ns delay
  1567. // Read a big-endian temperature value
  1568. max6675_temp = 0;
  1569. for (uint8_t i = sizeof(max6675_temp); i--;) {
  1570. max6675_temp |= (
  1571. #if MAX6675_SEPARATE_SPI
  1572. max6675_spi.receive()
  1573. #else
  1574. spiRec()
  1575. #endif
  1576. );
  1577. if (i > 0) max6675_temp <<= 8; // shift left if not the last byte
  1578. }
  1579. WRITE_MAX6675(HIGH); // disable TT_MAX6675
  1580. if (max6675_temp & MAX6675_ERROR_MASK) {
  1581. SERIAL_ERROR_START();
  1582. SERIAL_ECHOPGM("Temp measurement error! ");
  1583. #if MAX6675_ERROR_MASK == 7
  1584. SERIAL_ECHOPGM("MAX31855 ");
  1585. if (max6675_temp & 1)
  1586. SERIAL_ECHOLNPGM("Open Circuit");
  1587. else if (max6675_temp & 2)
  1588. SERIAL_ECHOLNPGM("Short to GND");
  1589. else if (max6675_temp & 4)
  1590. SERIAL_ECHOLNPGM("Short to VCC");
  1591. #else
  1592. SERIAL_ECHOLNPGM("MAX6675");
  1593. #endif
  1594. // Thermocouple open
  1595. max6675_temp = 4 * (
  1596. #if COUNT_6675 > 1
  1597. hindex ? HEATER_1_MAX6675_TMAX : HEATER_0_MAX6675_TMAX
  1598. #elif ENABLED(HEATER_1_USES_MAX6675)
  1599. HEATER_1_MAX6675_TMAX
  1600. #else
  1601. HEATER_0_MAX6675_TMAX
  1602. #endif
  1603. );
  1604. }
  1605. else
  1606. max6675_temp >>= MAX6675_DISCARD_BITS;
  1607. #if ENABLED(MAX6675_IS_MAX31855)
  1608. if (max6675_temp & 0x00002000) max6675_temp |= 0xFFFFC000; // Support negative temperature
  1609. #endif
  1610. #if COUNT_6675 > 1
  1611. max6675_temp_previous[hindex] = max6675_temp;
  1612. #endif
  1613. return int(max6675_temp);
  1614. }
  1615. #endif // HAS_MAX6675
  1616. /**
  1617. * Get raw temperatures
  1618. */
  1619. void Temperature::set_current_temp_raw() {
  1620. #if HAS_TEMP_ADC_0 && DISABLED(HEATER_0_USES_MAX6675)
  1621. current_temperature_raw[0] = raw_temp_value[0];
  1622. #endif
  1623. #if HAS_TEMP_ADC_1
  1624. #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
  1625. redundant_temperature_raw = raw_temp_value[1];
  1626. #elif DISABLED(HEATER_1_USES_MAX6675)
  1627. current_temperature_raw[1] = raw_temp_value[1];
  1628. #endif
  1629. #if HAS_TEMP_ADC_2
  1630. current_temperature_raw[2] = raw_temp_value[2];
  1631. #if HAS_TEMP_ADC_3
  1632. current_temperature_raw[3] = raw_temp_value[3];
  1633. #if HAS_TEMP_ADC_4
  1634. current_temperature_raw[4] = raw_temp_value[4];
  1635. #if HAS_TEMP_ADC_5
  1636. current_temperature_raw[5] = raw_temp_value[5];
  1637. #endif // HAS_TEMP_ADC_5
  1638. #endif // HAS_TEMP_ADC_4
  1639. #endif // HAS_TEMP_ADC_3
  1640. #endif // HAS_TEMP_ADC_2
  1641. #endif // HAS_TEMP_ADC_1
  1642. #if HAS_HEATED_BED
  1643. current_temperature_bed_raw = raw_temp_bed_value;
  1644. #endif
  1645. #if HAS_TEMP_CHAMBER
  1646. current_temperature_chamber_raw = raw_temp_chamber_value;
  1647. #endif
  1648. temp_meas_ready = true;
  1649. }
  1650. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  1651. uint32_t raw_filwidth_value; // = 0
  1652. #endif
  1653. void Temperature::readings_ready() {
  1654. // Update the raw values if they've been read. Else we could be updating them during reading.
  1655. if (!temp_meas_ready) set_current_temp_raw();
  1656. // Filament Sensor - can be read any time since IIR filtering is used
  1657. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  1658. current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
  1659. #endif
  1660. ZERO(raw_temp_value);
  1661. #if HAS_HEATED_BED
  1662. raw_temp_bed_value = 0;
  1663. #endif
  1664. #if HAS_TEMP_CHAMBER
  1665. raw_temp_chamber_value = 0;
  1666. #endif
  1667. #define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) > (HEATER_##N##_RAW_HI_TEMP) ? -1 : 1)
  1668. int constexpr temp_dir[] = {
  1669. #if ENABLED(HEATER_0_USES_MAX6675)
  1670. 0
  1671. #else
  1672. TEMPDIR(0)
  1673. #endif
  1674. #if HOTENDS > 1
  1675. , TEMPDIR(1)
  1676. #if HOTENDS > 2
  1677. , TEMPDIR(2)
  1678. #if HOTENDS > 3
  1679. , TEMPDIR(3)
  1680. #if HOTENDS > 4
  1681. , TEMPDIR(4)
  1682. #if HOTENDS > 5
  1683. , TEMPDIR(5)
  1684. #endif // HOTENDS > 5
  1685. #endif // HOTENDS > 4
  1686. #endif // HOTENDS > 3
  1687. #endif // HOTENDS > 2
  1688. #endif // HOTENDS > 1
  1689. };
  1690. for (uint8_t e = 0; e < COUNT(temp_dir); e++) {
  1691. const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir;
  1692. const bool heater_on = (target_temperature[e] > 0)
  1693. #if ENABLED(PIDTEMP)
  1694. || (soft_pwm_amount[e] > 0)
  1695. #endif
  1696. ;
  1697. if (rawtemp > maxttemp_raw[e] * tdir) max_temp_error(e);
  1698. if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && heater_on) {
  1699. #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
  1700. if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)
  1701. #endif
  1702. min_temp_error(e);
  1703. }
  1704. #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED
  1705. else
  1706. consecutive_low_temperature_error[e] = 0;
  1707. #endif
  1708. }
  1709. #if HAS_HEATED_BED
  1710. #if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
  1711. #define BEDCMP(A,B) ((A)<=(B))
  1712. #else
  1713. #define BEDCMP(A,B) ((A)>=(B))
  1714. #endif
  1715. const bool bed_on = (target_temperature_bed > 0)
  1716. #if ENABLED(PIDTEMPBED)
  1717. || (soft_pwm_amount_bed > 0)
  1718. #endif
  1719. ;
  1720. if (BEDCMP(current_temperature_bed_raw, bed_maxttemp_raw)) max_temp_error(-1);
  1721. if (BEDCMP(bed_minttemp_raw, current_temperature_bed_raw) && bed_on) min_temp_error(-1);
  1722. #endif
  1723. }
  1724. /**
  1725. * Timer 0 is shared with millies so don't change the prescaler.
  1726. *
  1727. * On AVR this ISR uses the compare method so it runs at the base
  1728. * frequency (16 MHz / 64 / 256 = 976.5625 Hz), but at the TCNT0 set
  1729. * in OCR0B above (128 or halfway between OVFs).
  1730. *
  1731. * - Manage PWM to all the heaters and fan
  1732. * - Prepare or Measure one of the raw ADC sensor values
  1733. * - Check new temperature values for MIN/MAX errors (kill on error)
  1734. * - Step the babysteps value for each axis towards 0
  1735. * - For PINS_DEBUGGING, monitor and report endstop pins
  1736. * - For ENDSTOP_INTERRUPTS_FEATURE check endstops if flagged
  1737. * - Call planner.tick to count down its "ignore" time
  1738. */
  1739. HAL_TEMP_TIMER_ISR {
  1740. HAL_timer_isr_prologue(TEMP_TIMER_NUM);
  1741. Temperature::isr();
  1742. HAL_timer_isr_epilogue(TEMP_TIMER_NUM);
  1743. }
  1744. void Temperature::isr() {
  1745. static int8_t temp_count = -1;
  1746. static ADCSensorState adc_sensor_state = StartupDelay;
  1747. static uint8_t pwm_count = _BV(SOFT_PWM_SCALE);
  1748. // avoid multiple loads of pwm_count
  1749. uint8_t pwm_count_tmp = pwm_count;
  1750. #if HAS_ADC_BUTTONS
  1751. static unsigned int raw_ADCKey_value = 0;
  1752. #endif
  1753. // Static members for each heater
  1754. #if ENABLED(SLOW_PWM_HEATERS)
  1755. static uint8_t slow_pwm_count = 0;
  1756. #define ISR_STATICS(n) \
  1757. static uint8_t soft_pwm_count_ ## n, \
  1758. state_heater_ ## n = 0, \
  1759. state_timer_heater_ ## n = 0
  1760. #else
  1761. #define ISR_STATICS(n) static uint8_t soft_pwm_count_ ## n = 0
  1762. #endif
  1763. // Statics per heater
  1764. ISR_STATICS(0);
  1765. #if HOTENDS > 1
  1766. ISR_STATICS(1);
  1767. #if HOTENDS > 2
  1768. ISR_STATICS(2);
  1769. #if HOTENDS > 3
  1770. ISR_STATICS(3);
  1771. #if HOTENDS > 4
  1772. ISR_STATICS(4);
  1773. #if HOTENDS > 5
  1774. ISR_STATICS(5);
  1775. #endif // HOTENDS > 5
  1776. #endif // HOTENDS > 4
  1777. #endif // HOTENDS > 3
  1778. #endif // HOTENDS > 2
  1779. #endif // HOTENDS > 1
  1780. #if HAS_HEATED_BED
  1781. ISR_STATICS(BED);
  1782. #endif
  1783. #if DISABLED(SLOW_PWM_HEATERS)
  1784. constexpr uint8_t pwm_mask =
  1785. #if ENABLED(SOFT_PWM_DITHER)
  1786. _BV(SOFT_PWM_SCALE) - 1
  1787. #else
  1788. 0
  1789. #endif
  1790. ;
  1791. /**
  1792. * Standard heater PWM modulation
  1793. */
  1794. if (pwm_count_tmp >= 127) {
  1795. pwm_count_tmp -= 127;
  1796. soft_pwm_count_0 = (soft_pwm_count_0 & pwm_mask) + soft_pwm_amount[0];
  1797. WRITE_HEATER_0(soft_pwm_count_0 > pwm_mask ? HIGH : LOW);
  1798. #if HOTENDS > 1
  1799. soft_pwm_count_1 = (soft_pwm_count_1 & pwm_mask) + soft_pwm_amount[1];
  1800. WRITE_HEATER_1(soft_pwm_count_1 > pwm_mask ? HIGH : LOW);
  1801. #if HOTENDS > 2
  1802. soft_pwm_count_2 = (soft_pwm_count_2 & pwm_mask) + soft_pwm_amount[2];
  1803. WRITE_HEATER_2(soft_pwm_count_2 > pwm_mask ? HIGH : LOW);
  1804. #if HOTENDS > 3
  1805. soft_pwm_count_3 = (soft_pwm_count_3 & pwm_mask) + soft_pwm_amount[3];
  1806. WRITE_HEATER_3(soft_pwm_count_3 > pwm_mask ? HIGH : LOW);
  1807. #if HOTENDS > 4
  1808. soft_pwm_count_4 = (soft_pwm_count_4 & pwm_mask) + soft_pwm_amount[4];
  1809. WRITE_HEATER_4(soft_pwm_count_4 > pwm_mask ? HIGH : LOW);
  1810. #if HOTENDS > 5
  1811. soft_pwm_count_5 = (soft_pwm_count_5 & pwm_mask) + soft_pwm_amount[5];
  1812. WRITE_HEATER_5(soft_pwm_count_5 > pwm_mask ? HIGH : LOW);
  1813. #endif // HOTENDS > 5
  1814. #endif // HOTENDS > 4
  1815. #endif // HOTENDS > 3
  1816. #endif // HOTENDS > 2
  1817. #endif // HOTENDS > 1
  1818. #if HAS_HEATED_BED
  1819. soft_pwm_count_BED = (soft_pwm_count_BED & pwm_mask) + soft_pwm_amount_bed;
  1820. WRITE_HEATER_BED(soft_pwm_count_BED > pwm_mask ? HIGH : LOW);
  1821. #endif
  1822. #if ENABLED(FAN_SOFT_PWM)
  1823. #if HAS_FAN0
  1824. soft_pwm_count_fan[0] = (soft_pwm_count_fan[0] & pwm_mask) + (soft_pwm_amount_fan[0] >> 1);
  1825. WRITE_FAN(soft_pwm_count_fan[0] > pwm_mask ? HIGH : LOW);
  1826. #endif
  1827. #if HAS_FAN1
  1828. soft_pwm_count_fan[1] = (soft_pwm_count_fan[1] & pwm_mask) + (soft_pwm_amount_fan[1] >> 1);
  1829. WRITE_FAN1(soft_pwm_count_fan[1] > pwm_mask ? HIGH : LOW);
  1830. #endif
  1831. #if HAS_FAN2
  1832. soft_pwm_count_fan[2] = (soft_pwm_count_fan[2] & pwm_mask) + (soft_pwm_amount_fan[2] >> 1);
  1833. WRITE_FAN2(soft_pwm_count_fan[2] > pwm_mask ? HIGH : LOW);
  1834. #endif
  1835. #endif
  1836. }
  1837. else {
  1838. if (soft_pwm_count_0 <= pwm_count_tmp) WRITE_HEATER_0(LOW);
  1839. #if HOTENDS > 1
  1840. if (soft_pwm_count_1 <= pwm_count_tmp) WRITE_HEATER_1(LOW);
  1841. #if HOTENDS > 2
  1842. if (soft_pwm_count_2 <= pwm_count_tmp) WRITE_HEATER_2(LOW);
  1843. #if HOTENDS > 3
  1844. if (soft_pwm_count_3 <= pwm_count_tmp) WRITE_HEATER_3(LOW);
  1845. #if HOTENDS > 4
  1846. if (soft_pwm_count_4 <= pwm_count_tmp) WRITE_HEATER_4(LOW);
  1847. #if HOTENDS > 5
  1848. if (soft_pwm_count_5 <= pwm_count_tmp) WRITE_HEATER_5(LOW);
  1849. #endif // HOTENDS > 5
  1850. #endif // HOTENDS > 4
  1851. #endif // HOTENDS > 3
  1852. #endif // HOTENDS > 2
  1853. #endif // HOTENDS > 1
  1854. #if HAS_HEATED_BED
  1855. if (soft_pwm_count_BED <= pwm_count_tmp) WRITE_HEATER_BED(LOW);
  1856. #endif
  1857. #if ENABLED(FAN_SOFT_PWM)
  1858. #if HAS_FAN0
  1859. if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(LOW);
  1860. #endif
  1861. #if HAS_FAN1
  1862. if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN1(LOW);
  1863. #endif
  1864. #if HAS_FAN2
  1865. if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN2(LOW);
  1866. #endif
  1867. #endif
  1868. }
  1869. // SOFT_PWM_SCALE to frequency:
  1870. //
  1871. // 0: 16000000/64/256/128 = 7.6294 Hz
  1872. // 1: / 64 = 15.2588 Hz
  1873. // 2: / 32 = 30.5176 Hz
  1874. // 3: / 16 = 61.0352 Hz
  1875. // 4: / 8 = 122.0703 Hz
  1876. // 5: / 4 = 244.1406 Hz
  1877. pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE);
  1878. #else // SLOW_PWM_HEATERS
  1879. /**
  1880. * SLOW PWM HEATERS
  1881. *
  1882. * For relay-driven heaters
  1883. */
  1884. #ifndef MIN_STATE_TIME
  1885. #define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds
  1886. #endif
  1887. // Macros for Slow PWM timer logic
  1888. #define _SLOW_PWM_ROUTINE(NR, src) \
  1889. soft_pwm_count_ ##NR = src; \
  1890. if (soft_pwm_count_ ##NR > 0) { \
  1891. if (state_timer_heater_ ##NR == 0) { \
  1892. if (state_heater_ ##NR == 0) state_timer_heater_ ##NR = MIN_STATE_TIME; \
  1893. state_heater_ ##NR = 1; \
  1894. WRITE_HEATER_ ##NR(1); \
  1895. } \
  1896. } \
  1897. else { \
  1898. if (state_timer_heater_ ##NR == 0) { \
  1899. if (state_heater_ ##NR == 1) state_timer_heater_ ##NR = MIN_STATE_TIME; \
  1900. state_heater_ ##NR = 0; \
  1901. WRITE_HEATER_ ##NR(0); \
  1902. } \
  1903. }
  1904. #define SLOW_PWM_ROUTINE(n) _SLOW_PWM_ROUTINE(n, soft_pwm_amount[n])
  1905. #define PWM_OFF_ROUTINE(NR) \
  1906. if (soft_pwm_count_ ##NR < slow_pwm_count) { \
  1907. if (state_timer_heater_ ##NR == 0) { \
  1908. if (state_heater_ ##NR == 1) state_timer_heater_ ##NR = MIN_STATE_TIME; \
  1909. state_heater_ ##NR = 0; \
  1910. WRITE_HEATER_ ##NR (0); \
  1911. } \
  1912. }
  1913. if (slow_pwm_count == 0) {
  1914. SLOW_PWM_ROUTINE(0);
  1915. #if HOTENDS > 1
  1916. SLOW_PWM_ROUTINE(1);
  1917. #if HOTENDS > 2
  1918. SLOW_PWM_ROUTINE(2);
  1919. #if HOTENDS > 3
  1920. SLOW_PWM_ROUTINE(3);
  1921. #if HOTENDS > 4
  1922. SLOW_PWM_ROUTINE(4);
  1923. #if HOTENDS > 5
  1924. SLOW_PWM_ROUTINE(5);
  1925. #endif // HOTENDS > 5
  1926. #endif // HOTENDS > 4
  1927. #endif // HOTENDS > 3
  1928. #endif // HOTENDS > 2
  1929. #endif // HOTENDS > 1
  1930. #if HAS_HEATED_BED
  1931. _SLOW_PWM_ROUTINE(BED, soft_pwm_amount_bed); // BED
  1932. #endif
  1933. } // slow_pwm_count == 0
  1934. PWM_OFF_ROUTINE(0);
  1935. #if HOTENDS > 1
  1936. PWM_OFF_ROUTINE(1);
  1937. #if HOTENDS > 2
  1938. PWM_OFF_ROUTINE(2);
  1939. #if HOTENDS > 3
  1940. PWM_OFF_ROUTINE(3);
  1941. #if HOTENDS > 4
  1942. PWM_OFF_ROUTINE(4);
  1943. #if HOTENDS > 5
  1944. PWM_OFF_ROUTINE(5);
  1945. #endif // HOTENDS > 5
  1946. #endif // HOTENDS > 4
  1947. #endif // HOTENDS > 3
  1948. #endif // HOTENDS > 2
  1949. #endif // HOTENDS > 1
  1950. #if HAS_HEATED_BED
  1951. PWM_OFF_ROUTINE(BED); // BED
  1952. #endif
  1953. #if ENABLED(FAN_SOFT_PWM)
  1954. if (pwm_count_tmp >= 127) {
  1955. pwm_count_tmp = 0;
  1956. #if HAS_FAN0
  1957. soft_pwm_count_fan[0] = soft_pwm_amount_fan[0] >> 1;
  1958. WRITE_FAN(soft_pwm_count_fan[0] > 0 ? HIGH : LOW);
  1959. #endif
  1960. #if HAS_FAN1
  1961. soft_pwm_count_fan[1] = soft_pwm_amount_fan[1] >> 1;
  1962. WRITE_FAN1(soft_pwm_count_fan[1] > 0 ? HIGH : LOW);
  1963. #endif
  1964. #if HAS_FAN2
  1965. soft_pwm_count_fan[2] = soft_pwm_amount_fan[2] >> 1;
  1966. WRITE_FAN2(soft_pwm_count_fan[2] > 0 ? HIGH : LOW);
  1967. #endif
  1968. }
  1969. #if HAS_FAN0
  1970. if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(LOW);
  1971. #endif
  1972. #if HAS_FAN1
  1973. if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN1(LOW);
  1974. #endif
  1975. #if HAS_FAN2
  1976. if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN2(LOW);
  1977. #endif
  1978. #endif // FAN_SOFT_PWM
  1979. // SOFT_PWM_SCALE to frequency:
  1980. //
  1981. // 0: 16000000/64/256/128 = 7.6294 Hz
  1982. // 1: / 64 = 15.2588 Hz
  1983. // 2: / 32 = 30.5176 Hz
  1984. // 3: / 16 = 61.0352 Hz
  1985. // 4: / 8 = 122.0703 Hz
  1986. // 5: / 4 = 244.1406 Hz
  1987. pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE);
  1988. // increment slow_pwm_count only every 64th pwm_count,
  1989. // i.e. yielding a PWM frequency of 16/128 Hz (8s).
  1990. if (((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0) {
  1991. slow_pwm_count++;
  1992. slow_pwm_count &= 0x7F;
  1993. if (state_timer_heater_0 > 0) state_timer_heater_0--;
  1994. #if HOTENDS > 1
  1995. if (state_timer_heater_1 > 0) state_timer_heater_1--;
  1996. #if HOTENDS > 2
  1997. if (state_timer_heater_2 > 0) state_timer_heater_2--;
  1998. #if HOTENDS > 3
  1999. if (state_timer_heater_3 > 0) state_timer_heater_3--;
  2000. #if HOTENDS > 4
  2001. if (state_timer_heater_4 > 0) state_timer_heater_4--;
  2002. #if HOTENDS > 5
  2003. if (state_timer_heater_5 > 0) state_timer_heater_5--;
  2004. #endif // HOTENDS > 5
  2005. #endif // HOTENDS > 4
  2006. #endif // HOTENDS > 3
  2007. #endif // HOTENDS > 2
  2008. #endif // HOTENDS > 1
  2009. #if HAS_HEATED_BED
  2010. if (state_timer_heater_BED > 0) state_timer_heater_BED--;
  2011. #endif
  2012. } // ((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0
  2013. #endif // SLOW_PWM_HEATERS
  2014. //
  2015. // Update lcd buttons 488 times per second
  2016. //
  2017. static bool do_buttons;
  2018. if ((do_buttons ^= true)) ui.update_buttons();
  2019. /**
  2020. * One sensor is sampled on every other call of the ISR.
  2021. * Each sensor is read 16 (OVERSAMPLENR) times, taking the average.
  2022. *
  2023. * On each Prepare pass, ADC is started for a sensor pin.
  2024. * On the next pass, the ADC value is read and accumulated.
  2025. *
  2026. * This gives each ADC 0.9765ms to charge up.
  2027. */
  2028. #define ACCUMULATE_ADC(var) do{ \
  2029. if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; \
  2030. else var += HAL_READ_ADC(); \
  2031. }while(0)
  2032. ADCSensorState next_sensor_state = adc_sensor_state < SensorsReady ? (ADCSensorState)(int(adc_sensor_state) + 1) : StartSampling;
  2033. switch (adc_sensor_state) {
  2034. case SensorsReady: {
  2035. // All sensors have been read. Stay in this state for a few
  2036. // ISRs to save on calls to temp update/checking code below.
  2037. constexpr int8_t extra_loops = MIN_ADC_ISR_LOOPS - (int8_t)SensorsReady;
  2038. static uint8_t delay_count = 0;
  2039. if (extra_loops > 0) {
  2040. if (delay_count == 0) delay_count = extra_loops; // Init this delay
  2041. if (--delay_count) // While delaying...
  2042. next_sensor_state = SensorsReady; // retain this state (else, next state will be 0)
  2043. break;
  2044. }
  2045. else {
  2046. adc_sensor_state = StartSampling; // Fall-through to start sampling
  2047. next_sensor_state = (ADCSensorState)(int(StartSampling) + 1);
  2048. }
  2049. }
  2050. case StartSampling: // Start of sampling loops. Do updates/checks.
  2051. if (++temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
  2052. temp_count = 0;
  2053. readings_ready();
  2054. }
  2055. break;
  2056. #if HAS_TEMP_ADC_0
  2057. case PrepareTemp_0:
  2058. HAL_START_ADC(TEMP_0_PIN);
  2059. break;
  2060. case MeasureTemp_0:
  2061. ACCUMULATE_ADC(raw_temp_value[0]);
  2062. break;
  2063. #endif
  2064. #if HAS_HEATED_BED
  2065. case PrepareTemp_BED:
  2066. HAL_START_ADC(TEMP_BED_PIN);
  2067. break;
  2068. case MeasureTemp_BED:
  2069. ACCUMULATE_ADC(raw_temp_bed_value);
  2070. break;
  2071. #endif
  2072. #if HAS_TEMP_CHAMBER
  2073. case PrepareTemp_CHAMBER:
  2074. HAL_START_ADC(TEMP_CHAMBER_PIN);
  2075. break;
  2076. case MeasureTemp_CHAMBER:
  2077. ACCUMULATE_ADC(raw_temp_chamber_value);
  2078. break;
  2079. #endif
  2080. #if HAS_TEMP_ADC_1
  2081. case PrepareTemp_1:
  2082. HAL_START_ADC(TEMP_1_PIN);
  2083. break;
  2084. case MeasureTemp_1:
  2085. ACCUMULATE_ADC(raw_temp_value[1]);
  2086. break;
  2087. #endif
  2088. #if HAS_TEMP_ADC_2
  2089. case PrepareTemp_2:
  2090. HAL_START_ADC(TEMP_2_PIN);
  2091. break;
  2092. case MeasureTemp_2:
  2093. ACCUMULATE_ADC(raw_temp_value[2]);
  2094. break;
  2095. #endif
  2096. #if HAS_TEMP_ADC_3
  2097. case PrepareTemp_3:
  2098. HAL_START_ADC(TEMP_3_PIN);
  2099. break;
  2100. case MeasureTemp_3:
  2101. ACCUMULATE_ADC(raw_temp_value[3]);
  2102. break;
  2103. #endif
  2104. #if HAS_TEMP_ADC_4
  2105. case PrepareTemp_4:
  2106. HAL_START_ADC(TEMP_4_PIN);
  2107. break;
  2108. case MeasureTemp_4:
  2109. ACCUMULATE_ADC(raw_temp_value[4]);
  2110. break;
  2111. #endif
  2112. #if HAS_TEMP_ADC_5
  2113. case PrepareTemp_5:
  2114. HAL_START_ADC(TEMP_5_PIN);
  2115. break;
  2116. case MeasureTemp_5:
  2117. ACCUMULATE_ADC(raw_temp_value[5]);
  2118. break;
  2119. #endif
  2120. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  2121. case Prepare_FILWIDTH:
  2122. HAL_START_ADC(FILWIDTH_PIN);
  2123. break;
  2124. case Measure_FILWIDTH:
  2125. if (!HAL_ADC_READY())
  2126. next_sensor_state = adc_sensor_state; // redo this state
  2127. else if (HAL_READ_ADC() > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read.
  2128. raw_filwidth_value -= raw_filwidth_value >> 7; // Subtract 1/128th of the raw_filwidth_value
  2129. raw_filwidth_value += uint32_t(HAL_READ_ADC()) << 7; // Add new ADC reading, scaled by 128
  2130. }
  2131. break;
  2132. #endif
  2133. #if HAS_ADC_BUTTONS
  2134. case Prepare_ADC_KEY:
  2135. HAL_START_ADC(ADC_KEYPAD_PIN);
  2136. break;
  2137. case Measure_ADC_KEY:
  2138. if (!HAL_ADC_READY())
  2139. next_sensor_state = adc_sensor_state; // redo this state
  2140. else if (ADCKey_count < 16) {
  2141. raw_ADCKey_value = HAL_READ_ADC();
  2142. if (raw_ADCKey_value > 900) {
  2143. //ADC Key release
  2144. ADCKey_count = 0;
  2145. current_ADCKey_raw = 0;
  2146. }
  2147. else {
  2148. current_ADCKey_raw += raw_ADCKey_value;
  2149. ADCKey_count++;
  2150. }
  2151. }
  2152. break;
  2153. #endif // ADC_KEYPAD
  2154. case StartupDelay: break;
  2155. } // switch(adc_sensor_state)
  2156. // Go to the next state
  2157. adc_sensor_state = next_sensor_state;
  2158. //
  2159. // Additional ~1KHz Tasks
  2160. //
  2161. #if ENABLED(BABYSTEPPING)
  2162. LOOP_XYZ(axis) {
  2163. const int16_t curTodo = babystepsTodo[axis]; // get rid of volatile for performance
  2164. if (curTodo) {
  2165. stepper.babystep((AxisEnum)axis, curTodo > 0);
  2166. if (curTodo > 0) babystepsTodo[axis]--;
  2167. else babystepsTodo[axis]++;
  2168. }
  2169. }
  2170. #endif // BABYSTEPPING
  2171. // Poll endstops state, if required
  2172. endstops.poll();
  2173. // Periodically call the planner timer
  2174. planner.tick();
  2175. }
  2176. #if HAS_TEMP_SENSOR
  2177. #include "../gcode/gcode.h"
  2178. static void print_heater_state(const float &c, const float &t
  2179. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2180. , const float r
  2181. #endif
  2182. #if NUM_SERIAL > 1
  2183. , const int8_t port=-1
  2184. #endif
  2185. , const int8_t e=-3
  2186. ) {
  2187. #if !(HAS_HEATED_BED && HAS_TEMP_HOTEND && HAS_TEMP_CHAMBER) && HOTENDS <= 1
  2188. UNUSED(e);
  2189. #endif
  2190. SERIAL_CHAR_P(port, ' ');
  2191. SERIAL_CHAR_P(port,
  2192. #if HAS_TEMP_CHAMBER && HAS_HEATED_BED && HAS_TEMP_HOTEND
  2193. e == -2 ? 'C' : e == -1 ? 'B' : 'T'
  2194. #elif HAS_HEATED_BED && HAS_TEMP_HOTEND
  2195. e == -1 ? 'B' : 'T'
  2196. #elif HAS_TEMP_HOTEND
  2197. 'T'
  2198. #else
  2199. 'B'
  2200. #endif
  2201. );
  2202. #if HOTENDS > 1
  2203. if (e >= 0) SERIAL_CHAR_P(port, '0' + e);
  2204. #endif
  2205. SERIAL_CHAR_P(port, ':');
  2206. SERIAL_ECHO_P(port, c);
  2207. SERIAL_ECHOPAIR_P(port, " /" , t);
  2208. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2209. SERIAL_ECHOPAIR_P(port, " (", r / OVERSAMPLENR);
  2210. SERIAL_CHAR_P(port, ')');
  2211. #endif
  2212. delay(2);
  2213. }
  2214. void Temperature::print_heater_states(const uint8_t target_extruder
  2215. #if NUM_SERIAL > 1
  2216. , const int8_t port
  2217. #endif
  2218. ) {
  2219. #if HAS_TEMP_HOTEND
  2220. print_heater_state(degHotend(target_extruder), degTargetHotend(target_extruder)
  2221. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2222. , rawHotendTemp(target_extruder)
  2223. #endif
  2224. #if NUM_SERIAL > 1
  2225. , port
  2226. #endif
  2227. );
  2228. #endif
  2229. #if HAS_HEATED_BED
  2230. print_heater_state(degBed(), degTargetBed()
  2231. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2232. , rawBedTemp()
  2233. #endif
  2234. #if NUM_SERIAL > 1
  2235. , port
  2236. #endif
  2237. , -1 // BED
  2238. );
  2239. #endif
  2240. #if HAS_TEMP_CHAMBER
  2241. print_heater_state(degChamber(), 0
  2242. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2243. , rawChamberTemp()
  2244. #endif
  2245. , -2 // CHAMBER
  2246. );
  2247. #endif
  2248. #if HOTENDS > 1
  2249. HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e)
  2250. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2251. , rawHotendTemp(e)
  2252. #endif
  2253. #if NUM_SERIAL > 1
  2254. , port
  2255. #endif
  2256. , e
  2257. );
  2258. #endif
  2259. SERIAL_ECHOPGM_P(port, " @:");
  2260. SERIAL_ECHO_P(port, getHeaterPower(target_extruder));
  2261. #if HAS_HEATED_BED
  2262. SERIAL_ECHOPGM_P(port, " B@:");
  2263. SERIAL_ECHO_P(port, getHeaterPower(-1));
  2264. #endif
  2265. #if HOTENDS > 1
  2266. HOTEND_LOOP() {
  2267. SERIAL_ECHOPAIR_P(port, " @", e);
  2268. SERIAL_CHAR_P(port, ':');
  2269. SERIAL_ECHO_P(port, getHeaterPower(e));
  2270. }
  2271. #endif
  2272. }
  2273. #if ENABLED(AUTO_REPORT_TEMPERATURES)
  2274. uint8_t Temperature::auto_report_temp_interval;
  2275. millis_t Temperature::next_temp_report_ms;
  2276. void Temperature::auto_report_temperatures() {
  2277. if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) {
  2278. next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval;
  2279. print_heater_states(active_extruder);
  2280. SERIAL_EOL();
  2281. }
  2282. }
  2283. #endif // AUTO_REPORT_TEMPERATURES
  2284. #if ENABLED(ULTRA_LCD) || ENABLED(EXTENSIBLE_UI)
  2285. void Temperature::set_heating_message(const uint8_t e) {
  2286. const bool heating = isHeatingHotend(e);
  2287. #if HOTENDS > 1
  2288. ui.status_printf_P(0, heating ? PSTR("E%i " MSG_HEATING) : PSTR("E%i " MSG_COOLING), int(e + 1));
  2289. #else
  2290. ui.set_status_P(heating ? PSTR("E " MSG_HEATING) : PSTR("E " MSG_COOLING));
  2291. #endif
  2292. }
  2293. #endif
  2294. #if HAS_TEMP_HOTEND
  2295. #ifndef MIN_COOLING_SLOPE_DEG
  2296. #define MIN_COOLING_SLOPE_DEG 1.50
  2297. #endif
  2298. #ifndef MIN_COOLING_SLOPE_TIME
  2299. #define MIN_COOLING_SLOPE_TIME 60
  2300. #endif
  2301. bool Temperature::wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling/*=true*/
  2302. #if G26_CLICK_CAN_CANCEL
  2303. , const bool click_to_cancel/*=false*/
  2304. #endif
  2305. ) {
  2306. #if TEMP_RESIDENCY_TIME > 0
  2307. millis_t residency_start_ms = 0;
  2308. // Loop until the temperature has stabilized
  2309. #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL))
  2310. #else
  2311. // Loop until the temperature is very close target
  2312. #define TEMP_CONDITIONS (wants_to_cool ? isCoolingHotend(target_extruder) : isHeatingHotend(target_extruder))
  2313. #endif
  2314. #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
  2315. const GcodeSuite::MarlinBusyState old_busy_state = gcode.busy_state;
  2316. KEEPALIVE_STATE(NOT_BUSY);
  2317. #endif
  2318. #if ENABLED(PRINTER_EVENT_LEDS)
  2319. const float start_temp = degHotend(target_extruder);
  2320. printerEventLEDs.onHotendHeatingStart();
  2321. #endif
  2322. float target_temp = -1.0, old_temp = 9999.0;
  2323. bool wants_to_cool = false;
  2324. wait_for_heatup = true;
  2325. millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
  2326. do {
  2327. // Target temperature might be changed during the loop
  2328. if (target_temp != degTargetHotend(target_extruder)) {
  2329. wants_to_cool = isCoolingHotend(target_extruder);
  2330. target_temp = degTargetHotend(target_extruder);
  2331. // Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
  2332. if (no_wait_for_cooling && wants_to_cool) break;
  2333. }
  2334. now = millis();
  2335. if (ELAPSED(now, next_temp_ms)) { // Print temp & remaining time every 1s while waiting
  2336. next_temp_ms = now + 1000UL;
  2337. print_heater_states(target_extruder);
  2338. #if TEMP_RESIDENCY_TIME > 0
  2339. SERIAL_ECHOPGM(" W:");
  2340. if (residency_start_ms)
  2341. SERIAL_ECHO(long((((TEMP_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL));
  2342. else
  2343. SERIAL_CHAR('?');
  2344. #endif
  2345. SERIAL_EOL();
  2346. }
  2347. idle();
  2348. gcode.reset_stepper_timeout(); // Keep steppers powered
  2349. const float temp = degHotend(target_extruder);
  2350. #if ENABLED(PRINTER_EVENT_LEDS)
  2351. // Gradually change LED strip from violet to red as nozzle heats up
  2352. if (!wants_to_cool) printerEventLEDs.onHotendHeating(start_temp, temp, target_temp);
  2353. #endif
  2354. #if TEMP_RESIDENCY_TIME > 0
  2355. const float temp_diff = ABS(target_temp - temp);
  2356. if (!residency_start_ms) {
  2357. // Start the TEMP_RESIDENCY_TIME timer when we reach target temp for the first time.
  2358. if (temp_diff < TEMP_WINDOW) residency_start_ms = now;
  2359. }
  2360. else if (temp_diff > TEMP_HYSTERESIS) {
  2361. // Restart the timer whenever the temperature falls outside the hysteresis.
  2362. residency_start_ms = now;
  2363. }
  2364. #endif
  2365. // Prevent a wait-forever situation if R is misused i.e. M109 R0
  2366. if (wants_to_cool) {
  2367. // break after MIN_COOLING_SLOPE_TIME seconds
  2368. // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG
  2369. if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) {
  2370. if (old_temp - temp < float(MIN_COOLING_SLOPE_DEG)) break;
  2371. next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME;
  2372. old_temp = temp;
  2373. }
  2374. }
  2375. #if G26_CLICK_CAN_CANCEL
  2376. if (click_to_cancel && ui.use_click()) {
  2377. wait_for_heatup = false;
  2378. ui.quick_feedback();
  2379. }
  2380. #endif
  2381. } while (wait_for_heatup && TEMP_CONDITIONS);
  2382. if (wait_for_heatup) {
  2383. ui.reset_status();
  2384. #if ENABLED(PRINTER_EVENT_LEDS)
  2385. printerEventLEDs.onHeatingDone();
  2386. #endif
  2387. }
  2388. #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
  2389. gcode.busy_state = old_busy_state;
  2390. #endif
  2391. return wait_for_heatup;
  2392. }
  2393. #endif // HAS_TEMP_HOTEND
  2394. #if HAS_HEATED_BED
  2395. #ifndef MIN_COOLING_SLOPE_DEG_BED
  2396. #define MIN_COOLING_SLOPE_DEG_BED 1.50
  2397. #endif
  2398. #ifndef MIN_COOLING_SLOPE_TIME_BED
  2399. #define MIN_COOLING_SLOPE_TIME_BED 60
  2400. #endif
  2401. bool Temperature::wait_for_bed(const bool no_wait_for_cooling/*=true*/
  2402. #if G26_CLICK_CAN_CANCEL
  2403. , const bool click_to_cancel/*=false*/
  2404. #endif
  2405. ) {
  2406. #if TEMP_BED_RESIDENCY_TIME > 0
  2407. millis_t residency_start_ms = 0;
  2408. // Loop until the temperature has stabilized
  2409. #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL))
  2410. #else
  2411. // Loop until the temperature is very close target
  2412. #define TEMP_BED_CONDITIONS (wants_to_cool ? isCoolingBed() : isHeatingBed())
  2413. #endif
  2414. float target_temp = -1, old_temp = 9999;
  2415. bool wants_to_cool = false;
  2416. wait_for_heatup = true;
  2417. millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
  2418. #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
  2419. const GcodeSuite::MarlinBusyState old_busy_state = gcode.busy_state;
  2420. KEEPALIVE_STATE(NOT_BUSY);
  2421. #endif
  2422. #if ENABLED(PRINTER_EVENT_LEDS)
  2423. const float start_temp = degBed();
  2424. printerEventLEDs.onBedHeatingStart();
  2425. #endif
  2426. do {
  2427. // Target temperature might be changed during the loop
  2428. if (target_temp != degTargetBed()) {
  2429. wants_to_cool = isCoolingBed();
  2430. target_temp = degTargetBed();
  2431. // Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
  2432. if (no_wait_for_cooling && wants_to_cool) break;
  2433. }
  2434. now = millis();
  2435. if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up.
  2436. next_temp_ms = now + 1000UL;
  2437. print_heater_states(active_extruder);
  2438. #if TEMP_BED_RESIDENCY_TIME > 0
  2439. SERIAL_ECHOPGM(" W:");
  2440. if (residency_start_ms)
  2441. SERIAL_ECHO(long((((TEMP_BED_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL));
  2442. else
  2443. SERIAL_CHAR('?');
  2444. #endif
  2445. SERIAL_EOL();
  2446. }
  2447. idle();
  2448. gcode.reset_stepper_timeout(); // Keep steppers powered
  2449. const float temp = degBed();
  2450. #if ENABLED(PRINTER_EVENT_LEDS)
  2451. // Gradually change LED strip from blue to violet as bed heats up
  2452. if (!wants_to_cool) printerEventLEDs.onBedHeating(start_temp, temp, target_temp);
  2453. #endif
  2454. #if TEMP_BED_RESIDENCY_TIME > 0
  2455. const float temp_diff = ABS(target_temp - temp);
  2456. if (!residency_start_ms) {
  2457. // Start the TEMP_BED_RESIDENCY_TIME timer when we reach target temp for the first time.
  2458. if (temp_diff < TEMP_BED_WINDOW) residency_start_ms = now;
  2459. }
  2460. else if (temp_diff > TEMP_BED_HYSTERESIS) {
  2461. // Restart the timer whenever the temperature falls outside the hysteresis.
  2462. residency_start_ms = now;
  2463. }
  2464. #endif // TEMP_BED_RESIDENCY_TIME > 0
  2465. // Prevent a wait-forever situation if R is misused i.e. M190 R0
  2466. if (wants_to_cool) {
  2467. // Break after MIN_COOLING_SLOPE_TIME_BED seconds
  2468. // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_BED
  2469. if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) {
  2470. if (old_temp - temp < float(MIN_COOLING_SLOPE_DEG_BED)) break;
  2471. next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME_BED;
  2472. old_temp = temp;
  2473. }
  2474. }
  2475. #if G26_CLICK_CAN_CANCEL
  2476. if (click_to_cancel && ui.use_click()) {
  2477. wait_for_heatup = false;
  2478. ui.quick_feedback();
  2479. }
  2480. #endif
  2481. } while (wait_for_heatup && TEMP_BED_CONDITIONS);
  2482. if (wait_for_heatup) ui.reset_status();
  2483. #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
  2484. gcode.busy_state = old_busy_state;
  2485. #endif
  2486. return wait_for_heatup;
  2487. }
  2488. #endif // HAS_HEATED_BED
  2489. #endif // HAS_TEMP_SENSOR