My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

menu_temperature.cpp 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 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 Menu
  24. //
  25. #include "../../inc/MarlinConfigPre.h"
  26. #if HAS_LCD_MENU
  27. #include "menu.h"
  28. #include "../../module/temperature.h"
  29. #if FAN_COUNT > 1 || ENABLED(SINGLENOZZLE)
  30. #include "../../module/motion.h"
  31. #endif
  32. #if ENABLED(SINGLENOZZLE)
  33. #include "../../module/tool_change.h"
  34. #endif
  35. // Initialized by settings.load()
  36. int16_t MarlinUI::preheat_hotend_temp[2], MarlinUI::preheat_bed_temp[2];
  37. uint8_t MarlinUI::preheat_fan_speed[2];
  38. //
  39. // "Temperature" submenu items
  40. //
  41. void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb, const uint8_t fan) {
  42. #if HOTENDS
  43. if (temph > 0) thermalManager.setTargetHotend(_MIN(heater_maxtemp[endnum] - 15, temph), endnum);
  44. #endif
  45. #if HAS_HEATED_BED
  46. if (tempb >= 0) thermalManager.setTargetBed(tempb);
  47. #else
  48. UNUSED(tempb);
  49. #endif
  50. #if FAN_COUNT > 0
  51. #if FAN_COUNT > 1
  52. thermalManager.set_fan_speed(active_extruder < FAN_COUNT ? active_extruder : 0, fan);
  53. #else
  54. thermalManager.set_fan_speed(0, fan);
  55. #endif
  56. #else
  57. UNUSED(fan);
  58. #endif
  59. ui.return_to_status();
  60. }
  61. #if HAS_TEMP_HOTEND
  62. inline void _preheat_end(const uint8_t m, const uint8_t e) {
  63. _lcd_preheat(e, ui.preheat_hotend_temp[m], -1, ui.preheat_fan_speed[m]);
  64. }
  65. #if HAS_HEATED_BED
  66. inline void _preheat_both(const uint8_t m, const uint8_t e) {
  67. _lcd_preheat(e, ui.preheat_hotend_temp[m], ui.preheat_bed_temp[m], ui.preheat_fan_speed[m]);
  68. }
  69. #endif
  70. #endif
  71. #if HAS_HEATED_BED
  72. inline void _preheat_bed(const uint8_t m) {
  73. _lcd_preheat(0, 0, ui.preheat_bed_temp[m], ui.preheat_fan_speed[m]);
  74. }
  75. #endif
  76. #if HAS_TEMP_HOTEND || HAS_HEATED_BED
  77. #define _PREHEAT_ITEMS(M,N) do{ \
  78. ACTION_ITEM_N(N, MSG_PREHEAT_##M##_H, []{ _preheat_both(M-1, MenuItemBase::itemIndex); }); \
  79. ACTION_ITEM_N(N, MSG_PREHEAT_##M##_END_E, []{ _preheat_end(M-1, MenuItemBase::itemIndex); }); \
  80. }while(0)
  81. #if HAS_HEATED_BED
  82. #define PREHEAT_ITEMS(M,N) _PREHEAT_ITEMS(M,N)
  83. #else
  84. #define PREHEAT_ITEMS(M,N) \
  85. ACTION_ITEM_N(N, MSG_PREHEAT_##M##_H, []{ _preheat_end(M-1, MenuItemBase::itemIndex); })
  86. #endif
  87. void menu_preheat_m1() {
  88. START_MENU();
  89. BACK_ITEM(MSG_TEMPERATURE);
  90. #if HOTENDS == 1
  91. #if HAS_HEATED_BED
  92. ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_both(0, 0); });
  93. ACTION_ITEM(MSG_PREHEAT_1_END, []{ _preheat_end(0, 0); });
  94. #else
  95. ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_end(0, 0); });
  96. #endif
  97. #elif HOTENDS > 1
  98. #if HAS_HEATED_BED
  99. _PREHEAT_ITEMS(1,0);
  100. #endif
  101. LOOP_S_L_N(n, 1, HOTENDS) PREHEAT_ITEMS(1,n);
  102. ACTION_ITEM(MSG_PREHEAT_1_ALL, []() {
  103. #if HAS_HEATED_BED
  104. _preheat_bed(0);
  105. #endif
  106. HOTEND_LOOP() thermalManager.setTargetHotend(ui.preheat_hotend_temp[0], e);
  107. });
  108. #endif // HOTENDS > 1
  109. #if HAS_HEATED_BED
  110. ACTION_ITEM(MSG_PREHEAT_1_BEDONLY, []{ _preheat_bed(0); });
  111. #endif
  112. END_MENU();
  113. }
  114. void menu_preheat_m2() {
  115. START_MENU();
  116. BACK_ITEM(MSG_TEMPERATURE);
  117. #if HOTENDS == 1
  118. #if HAS_HEATED_BED
  119. ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_both(1, 0); });
  120. ACTION_ITEM(MSG_PREHEAT_2_END, []{ _preheat_end(1, 0); });
  121. #else
  122. ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_end(1, 0); });
  123. #endif
  124. #elif HOTENDS > 1
  125. #if HAS_HEATED_BED
  126. _PREHEAT_ITEMS(2,0);
  127. #endif
  128. LOOP_S_L_N(n, 1, HOTENDS) PREHEAT_ITEMS(2,n);
  129. ACTION_ITEM(MSG_PREHEAT_2_ALL, []() {
  130. #if HAS_HEATED_BED
  131. _preheat_bed(1);
  132. #endif
  133. HOTEND_LOOP() thermalManager.setTargetHotend(ui.preheat_hotend_temp[1], e);
  134. });
  135. #endif // HOTENDS > 1
  136. #if HAS_HEATED_BED
  137. ACTION_ITEM(MSG_PREHEAT_2_BEDONLY, []{ _preheat_bed(1); });
  138. #endif
  139. END_MENU();
  140. }
  141. void lcd_cooldown() {
  142. thermalManager.zero_fan_speeds();
  143. thermalManager.disable_all_heaters();
  144. ui.return_to_status();
  145. }
  146. #endif // HAS_TEMP_HOTEND || HAS_HEATED_BED
  147. void menu_temperature() {
  148. START_MENU();
  149. BACK_ITEM(MSG_MAIN);
  150. //
  151. // Nozzle:
  152. // Nozzle [1-5]:
  153. //
  154. #if HOTENDS == 1
  155. EDIT_ITEM_FAST(int3, MSG_NOZZLE, &thermalManager.temp_hotend[0].target, 0, HEATER_0_MAXTEMP - 15, []{ thermalManager.start_watching_hotend(0); });
  156. #elif HOTENDS > 1
  157. HOTEND_LOOP()
  158. EDIT_ITEM_FAST_N(int3, e, MSG_NOZZLE_N, &thermalManager.temp_hotend[e].target, 0, heater_maxtemp[e] - 15, []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); });
  159. #endif
  160. #if ENABLED(SINGLENOZZLE)
  161. EDIT_ITEM_FAST(uint16_3, MSG_NOZZLE_STANDBY, &singlenozzle_temp[active_extruder ? 0 : 1], 0, HEATER_0_MAXTEMP - 15);
  162. #endif
  163. //
  164. // Bed:
  165. //
  166. #if HAS_HEATED_BED
  167. EDIT_ITEM_FAST(int3, MSG_BED, &thermalManager.temp_bed.target, 0, BED_MAXTEMP - 10, thermalManager.start_watching_bed);
  168. #endif
  169. //
  170. // Chamber:
  171. //
  172. #if HAS_HEATED_CHAMBER
  173. EDIT_ITEM_FAST(int3, MSG_CHAMBER, &thermalManager.temp_chamber.target, 0, CHAMBER_MAXTEMP - 10, thermalManager.start_watching_chamber);
  174. #endif
  175. //
  176. // Fan Speed:
  177. //
  178. #if FAN_COUNT > 0
  179. auto on_fan_update = []{
  180. thermalManager.set_fan_speed(MenuItemBase::itemIndex, editable.uint8);
  181. };
  182. #if HAS_FAN1 || HAS_FAN2 || HAS_FAN3 || HAS_FAN4 || HAS_FAN5 || HAS_FAN6 || HAS_FAN7
  183. auto fan_edit_items = [&](const uint8_t f) {
  184. editable.uint8 = thermalManager.fan_speed[f];
  185. EDIT_ITEM_FAST_N(percent, f, MSG_FAN_SPEED_N, &editable.uint8, 0, 255, on_fan_update);
  186. #if ENABLED(EXTRA_FAN_SPEED)
  187. EDIT_ITEM_FAST_N(percent, f, MSG_EXTRA_FAN_SPEED_N, &thermalManager.new_fan_speed[f], 3, 255);
  188. #endif
  189. };
  190. #endif
  191. #define SNFAN(N) (ENABLED(SINGLENOZZLE) && !HAS_FAN##N && EXTRUDERS > N)
  192. #if SNFAN(1) || SNFAN(2) || SNFAN(3) || SNFAN(4) || SNFAN(5) || SNFAN(6) || SNFAN(7)
  193. auto singlenozzle_item = [&](const uint8_t f) {
  194. editable.uint8 = thermalManager.fan_speed[f];
  195. EDIT_ITEM_FAST_N(percent, f, MSG_STORED_FAN_N, &editable.uint8, 0, 255, on_fan_update);
  196. };
  197. #endif
  198. #if HAS_FAN0
  199. editable.uint8 = thermalManager.fan_speed[0];
  200. EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_FAN_SPEED, &editable.uint8, 0, 255, on_fan_update);
  201. #if ENABLED(EXTRA_FAN_SPEED)
  202. EDIT_ITEM_FAST_N(percent, 0, MSG_FIRST_EXTRA_FAN_SPEED, &thermalManager.new_fan_speed[0], 3, 255);
  203. #endif
  204. #endif
  205. #if HAS_FAN1
  206. fan_edit_items(1);
  207. #elif SNFAN(1)
  208. singlenozzle_item(1);
  209. #endif
  210. #if HAS_FAN2
  211. fan_edit_items(2);
  212. #elif SNFAN(2)
  213. singlenozzle_item(1);
  214. #endif
  215. #if HAS_FAN3
  216. fan_edit_items(3);
  217. #elif SNFAN(3)
  218. singlenozzle_item(1);
  219. #endif
  220. #if HAS_FAN4
  221. fan_edit_items(4);
  222. #elif SNFAN(4)
  223. singlenozzle_item(1);
  224. #endif
  225. #if HAS_FAN5
  226. fan_edit_items(5);
  227. #elif SNFAN(5)
  228. singlenozzle_item(1);
  229. #endif
  230. #if HAS_FAN6
  231. fan_edit_items(6);
  232. #elif SNFAN(6)
  233. singlenozzle_item(1);
  234. #endif
  235. #if HAS_FAN7
  236. fan_edit_items(7);
  237. #elif SNFAN(7)
  238. singlenozzle_item(1);
  239. #endif
  240. #endif // FAN_COUNT > 0
  241. #if HAS_TEMP_HOTEND
  242. //
  243. // Preheat for Material 1 and 2
  244. //
  245. #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_4 != 0 || TEMP_SENSOR_5 != 0 || TEMP_SENSOR_6 != 0 || TEMP_SENSOR_7 != 0 || HAS_HEATED_BED
  246. SUBMENU(MSG_PREHEAT_1, menu_preheat_m1);
  247. SUBMENU(MSG_PREHEAT_2, menu_preheat_m2);
  248. #else
  249. ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_end(0, 0); });
  250. ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_end(1, 0); });
  251. #endif
  252. //
  253. // Cooldown
  254. //
  255. bool has_heat = false;
  256. HOTEND_LOOP() if (thermalManager.temp_hotend[HOTEND_INDEX].target) { has_heat = true; break; }
  257. #if HAS_TEMP_BED
  258. if (thermalManager.temp_bed.target) has_heat = true;
  259. #endif
  260. if (has_heat) ACTION_ITEM(MSG_COOLDOWN, lcd_cooldown);
  261. #endif // HAS_TEMP_HOTEND
  262. END_MENU();
  263. }
  264. #endif // HAS_LCD_MENU