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_configuration.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2019 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. // Configuration Menu
  24. //
  25. #include "../../inc/MarlinConfigPre.h"
  26. #if HAS_LCD_MENU
  27. #include "menu.h"
  28. #include "../../module/configuration_store.h"
  29. #if HAS_FILAMENT_SENSOR
  30. #include "../../feature/runout.h"
  31. #endif
  32. #if ENABLED(POWER_LOSS_RECOVERY)
  33. #include "../../feature/power_loss_recovery.h"
  34. #endif
  35. #if HAS_BED_PROBE
  36. #include "../../module/probe.h"
  37. #if ENABLED(BLTOUCH)
  38. #include "../../feature/bltouch.h"
  39. #endif
  40. #endif
  41. #define HAS_DEBUG_MENU ENABLED(LCD_PROGRESS_BAR_TEST)
  42. void menu_advanced_settings();
  43. #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION)
  44. void menu_delta_calibrate();
  45. #endif
  46. static void lcd_factory_settings() {
  47. settings.reset();
  48. #if HAS_BUZZER
  49. ui.completion_feedback();
  50. #endif
  51. }
  52. #if ENABLED(LCD_PROGRESS_BAR_TEST)
  53. #include "../lcdprint.h"
  54. static void progress_bar_test() {
  55. static int8_t bar_percent = 0;
  56. if (ui.use_click()) {
  57. ui.goto_previous_screen();
  58. ui.set_custom_characters(CHARSET_MENU);
  59. return;
  60. }
  61. bar_percent += (int8_t)ui.encoderPosition;
  62. LIMIT(bar_percent, 0, 100);
  63. ui.encoderPosition = 0;
  64. draw_menu_item_static(0, PSTR(MSG_PROGRESS_BAR_TEST), true, true);
  65. lcd_put_int((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2, bar_percent); lcd_put_wchar('%');
  66. lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent);
  67. }
  68. void _progress_bar_test() {
  69. ui.goto_screen(progress_bar_test);
  70. ui.set_custom_characters(CHARSET_INFO);
  71. }
  72. #endif // LCD_PROGRESS_BAR_TEST
  73. #if HAS_DEBUG_MENU
  74. void menu_debug() {
  75. START_MENU();
  76. MENU_BACK(MSG_CONFIGURATION);
  77. #if ENABLED(LCD_PROGRESS_BAR_TEST)
  78. MENU_ITEM(submenu, MSG_PROGRESS_BAR_TEST, _progress_bar_test);
  79. #endif
  80. END_MENU();
  81. }
  82. #endif
  83. #if EXTRUDERS > 1
  84. #include "../../module/tool_change.h"
  85. void menu_tool_change() {
  86. START_MENU();
  87. MENU_BACK(MSG_CONFIGURATION);
  88. #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
  89. static constexpr float max_extrude =
  90. #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
  91. EXTRUDE_MAXLENGTH
  92. #else
  93. 500
  94. #endif
  95. ;
  96. MENU_ITEM_EDIT(float3, MSG_FILAMENT_SWAP_LENGTH, &toolchange_settings.swap_length, 0, max_extrude);
  97. MENU_ITEM_EDIT(float3, MSG_FILAMENT_PURGE_LENGTH, &toolchange_settings.extra_prime, 0, max_extrude);
  98. MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_RETRACT_SPD, &toolchange_settings.retract_speed, 10, 5400);
  99. MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_PRIME_SPD, &toolchange_settings.prime_speed, 10, 5400);
  100. #endif
  101. MENU_ITEM_EDIT(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10);
  102. END_MENU();
  103. }
  104. #endif
  105. #if HAS_HOTEND_OFFSET
  106. #include "../../module/motion.h"
  107. #include "../../gcode/queue.h"
  108. void menu_tool_offsets() {
  109. auto _recalc_offsets = []{
  110. if (active_extruder && all_axes_known()) { // For the 2nd extruder re-home so the next tool-change gets the new offsets.
  111. queue.inject_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
  112. active_extruder = 0;
  113. }
  114. };
  115. START_MENU();
  116. MENU_BACK(MSG_CONFIGURATION);
  117. #if ENABLED(DUAL_X_CARRIAGE)
  118. MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float51, MSG_X_OFFSET, &hotend_offset[X_AXIS][1], float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets);
  119. #else
  120. MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52sign, MSG_X_OFFSET, &hotend_offset[X_AXIS][1], -99.0, 99.0, _recalc_offsets);
  121. #endif
  122. MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52sign, MSG_Y_OFFSET, &hotend_offset[Y_AXIS][1], -99.0, 99.0, _recalc_offsets);
  123. MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52sign, MSG_Z_OFFSET, &hotend_offset[Z_AXIS][1], Z_PROBE_LOW_POINT, 10.0, _recalc_offsets);
  124. #if ENABLED(EEPROM_SETTINGS)
  125. MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings);
  126. #endif
  127. END_MENU();
  128. }
  129. #endif
  130. #if ENABLED(DUAL_X_CARRIAGE)
  131. void menu_idex() {
  132. START_MENU();
  133. MENU_BACK(MSG_CONFIGURATION);
  134. MENU_ITEM(gcode, MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100"));
  135. const bool need_g28 = !(TEST(axis_known_position, Y_AXIS) && TEST(axis_known_position, Z_AXIS));
  136. MENU_ITEM(gcode, MSG_IDEX_MODE_DUPLICATE, need_g28
  137. ? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100") // If Y or Z is not homed, do a full G28 first
  138. : PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100")
  139. );
  140. MENU_ITEM(gcode, MSG_IDEX_MODE_MIRRORED_COPY, need_g28
  141. ? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100\nM605 S3 X200") // If Y or Z is not homed, do a full G28 first
  142. : PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100\nM605 S3 X200")
  143. );
  144. MENU_ITEM(gcode, MSG_IDEX_MODE_FULL_CTRL, PSTR("M605 S0\nG28 X"));
  145. END_MENU();
  146. }
  147. #endif
  148. #if ENABLED(BLTOUCH)
  149. #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU)
  150. void bltouch_report() {
  151. SERIAL_ECHOLNPAIR("EEPROM Last BLTouch Mode - ", (int)bltouch.last_written_mode);
  152. SERIAL_ECHOLNPGM("Configuration BLTouch Mode - "
  153. #if ENABLED(BLTOUCH_SET_5V_MODE)
  154. "5V"
  155. #else
  156. "OD"
  157. #endif
  158. );
  159. char mess[21];
  160. strcpy_P(mess, PSTR("BLTouch Mode - "));
  161. strcpy_P(&mess[15], bltouch.last_written_mode ? PSTR("5V") : PSTR("OD"));
  162. ui.set_status(mess);
  163. ui.return_to_status();
  164. }
  165. #endif
  166. void menu_bltouch() {
  167. START_MENU();
  168. MENU_BACK(MSG_CONFIGURATION);
  169. MENU_ITEM(function, MSG_BLTOUCH_RESET, bltouch._reset);
  170. MENU_ITEM(function, MSG_BLTOUCH_SELFTEST, bltouch._selftest);
  171. MENU_ITEM(function, MSG_BLTOUCH_DEPLOY, bltouch._deploy);
  172. MENU_ITEM(function, MSG_BLTOUCH_STOW, bltouch._stow);
  173. MENU_ITEM(function, MSG_BLTOUCH_SW_MODE, bltouch._set_SW_mode);
  174. #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU)
  175. MENU_ITEM(submenu, MSG_BLTOUCH_5V_MODE, []{
  176. do_select_screen(PSTR(MSG_BLTOUCH_5V_MODE), PSTR(MSG_BUTTON_CANCEL), bltouch._set_5V_mode, ui.goto_previous_screen, PSTR(MSG_BLTOUCH_MODE_CHANGE));
  177. });
  178. MENU_ITEM(submenu, MSG_BLTOUCH_OD_MODE, []{
  179. do_select_screen(PSTR(MSG_BLTOUCH_OD_MODE), PSTR(MSG_BUTTON_CANCEL), bltouch._set_OD_mode, ui.goto_previous_screen, PSTR(MSG_BLTOUCH_MODE_CHANGE));
  180. });
  181. MENU_ITEM(function, MSG_BLTOUCH_MODE_STORE, bltouch._mode_store);
  182. MENU_ITEM(submenu, MSG_BLTOUCH_MODE_STORE_5V, []{
  183. do_select_screen(PSTR(MSG_BLTOUCH_MODE_STORE_5V), PSTR(MSG_BUTTON_CANCEL), bltouch.mode_conv_5V, ui.goto_previous_screen, PSTR(MSG_BLTOUCH_MODE_CHANGE));
  184. });
  185. MENU_ITEM(submenu, MSG_BLTOUCH_MODE_STORE_OD, []{
  186. do_select_screen(PSTR(MSG_BLTOUCH_MODE_STORE_OD), PSTR(MSG_BUTTON_CANCEL), bltouch.mode_conv_OD, ui.goto_previous_screen, PSTR(MSG_BLTOUCH_MODE_CHANGE));
  187. });
  188. MENU_ITEM(function, MSG_BLTOUCH_MODE_ECHO, bltouch_report);
  189. #endif
  190. END_MENU();
  191. }
  192. #endif
  193. #if ENABLED(TOUCH_MI_PROBE)
  194. void menu_touchmi() {
  195. START_MENU();
  196. ui.defer_status_screen();
  197. MENU_BACK(MSG_CONFIGURATION);
  198. MENU_ITEM(gcode, MSG_TOUCHMI_INIT, PSTR("M851 Z0\nG28\nG1 F200 Z0"));
  199. MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset);
  200. MENU_ITEM(gcode, MSG_TOUCHMI_SAVE, PSTR("M500\nG1 F200 Z10"));
  201. MENU_ITEM(gcode, MSG_TOUCHMI_ZTEST, PSTR("G28\nG1 F200 Z0"));
  202. END_MENU();
  203. }
  204. #endif
  205. #if ENABLED(CASE_LIGHT_MENU)
  206. #include "../../feature/caselight.h"
  207. #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
  208. void menu_case_light() {
  209. START_MENU();
  210. MENU_BACK(MSG_CONFIGURATION);
  211. MENU_ITEM_EDIT_CALLBACK(uint8, MSG_CASE_LIGHT_BRIGHTNESS, &case_light_brightness, 0, 255, update_case_light, true);
  212. MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light);
  213. END_MENU();
  214. }
  215. #endif
  216. #endif
  217. #if ENABLED(FWRETRACT)
  218. #include "../../feature/fwretract.h"
  219. void menu_config_retract() {
  220. START_MENU();
  221. MENU_BACK(MSG_CONFIGURATION);
  222. #if ENABLED(FWRETRACT_AUTORETRACT)
  223. MENU_ITEM_EDIT_CALLBACK(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled, fwretract.refresh_autoretract);
  224. #endif
  225. MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT, &fwretract.settings.retract_length, 0, 100);
  226. #if EXTRUDERS > 1
  227. MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_SWAP, &fwretract.settings.swap_retract_length, 0, 100);
  228. #endif
  229. MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &fwretract.settings.retract_feedrate_mm_s, 1, 999);
  230. MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_ZHOP, &fwretract.settings.retract_zraise, 0, 999);
  231. MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER, &fwretract.settings.retract_recover_extra, -100, 100);
  232. #if EXTRUDERS > 1
  233. MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.settings.swap_retract_recover_extra, -100, 100);
  234. #endif
  235. MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.settings.retract_recover_feedrate_mm_s, 1, 999);
  236. #if EXTRUDERS > 1
  237. MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.settings.swap_retract_recover_feedrate_mm_s, 1, 999);
  238. #endif
  239. END_MENU();
  240. }
  241. #endif
  242. #if DISABLED(SLIM_LCD_MENUS)
  243. void _menu_configuration_preheat_settings(const uint8_t material) {
  244. #if HOTENDS > 5
  245. #define MINTEMP_ALL _MIN(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP, HEATER_3_MINTEMP, HEATER_4_MINTEMP, HEATER_5_MINTEMP)
  246. #define MAXTEMP_ALL _MAX(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP, HEATER_5_MAXTEMP)
  247. #elif HOTENDS > 4
  248. #define MINTEMP_ALL _MIN(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP, HEATER_3_MINTEMP, HEATER_4_MINTEMP)
  249. #define MAXTEMP_ALL _MAX(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP)
  250. #elif HOTENDS > 3
  251. #define MINTEMP_ALL _MIN(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP, HEATER_3_MINTEMP)
  252. #define MAXTEMP_ALL _MAX(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP)
  253. #elif HOTENDS > 2
  254. #define MINTEMP_ALL _MIN(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP)
  255. #define MAXTEMP_ALL _MAX(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP)
  256. #elif HOTENDS > 1
  257. #define MINTEMP_ALL _MIN(HEATER_0_MINTEMP, HEATER_1_MINTEMP)
  258. #define MAXTEMP_ALL _MAX(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP)
  259. #else
  260. #define MINTEMP_ALL HEATER_0_MINTEMP
  261. #define MAXTEMP_ALL HEATER_0_MAXTEMP
  262. #endif
  263. START_MENU();
  264. MENU_BACK(MSG_CONFIGURATION);
  265. MENU_ITEM_EDIT(percent, MSG_FAN_SPEED, &ui.preheat_fan_speed[material], 0, 255);
  266. #if HAS_TEMP_HOTEND
  267. MENU_ITEM_EDIT(int3, MSG_NOZZLE, &ui.preheat_hotend_temp[material], MINTEMP_ALL, MAXTEMP_ALL - 15);
  268. #endif
  269. #if HAS_HEATED_BED
  270. MENU_ITEM_EDIT(int3, MSG_BED, &ui.preheat_bed_temp[material], BED_MINTEMP, BED_MAXTEMP - 10);
  271. #endif
  272. #if ENABLED(EEPROM_SETTINGS)
  273. MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings);
  274. #endif
  275. END_MENU();
  276. }
  277. void menu_preheat_material1_settings() { _menu_configuration_preheat_settings(0); }
  278. void menu_preheat_material2_settings() { _menu_configuration_preheat_settings(1); }
  279. #endif
  280. void menu_configuration() {
  281. START_MENU();
  282. MENU_BACK(MSG_MAIN);
  283. //
  284. // Debug Menu when certain options are enabled
  285. //
  286. #if HAS_DEBUG_MENU
  287. MENU_ITEM(submenu, MSG_DEBUG_MENU, menu_debug);
  288. #endif
  289. MENU_ITEM(submenu, MSG_ADVANCED_SETTINGS, menu_advanced_settings);
  290. #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
  291. MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset);
  292. #elif HAS_BED_PROBE
  293. MENU_ITEM_EDIT(float52, MSG_ZPROBE_ZOFFSET, &zprobe_offset[Z_AXIS], Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX);
  294. #endif
  295. const bool busy = printer_busy();
  296. if (!busy) {
  297. //
  298. // Delta Calibration
  299. //
  300. #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION)
  301. MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, menu_delta_calibrate);
  302. #endif
  303. #if HAS_HOTEND_OFFSET
  304. MENU_ITEM(submenu, MSG_OFFSETS_MENU, menu_tool_offsets);
  305. #endif
  306. #if ENABLED(DUAL_X_CARRIAGE)
  307. MENU_ITEM(submenu, MSG_IDEX_MENU, menu_idex);
  308. #endif
  309. #if ENABLED(BLTOUCH)
  310. MENU_ITEM(submenu, MSG_BLTOUCH, menu_bltouch);
  311. #endif
  312. #if ENABLED(TOUCH_MI_PROBE)
  313. MENU_ITEM(submenu, MSG_TOUCHMI_PROBE, menu_touchmi);
  314. #endif
  315. }
  316. //
  317. // Set single nozzle filament retract and prime length
  318. //
  319. #if EXTRUDERS > 1
  320. MENU_ITEM(submenu, MSG_TOOL_CHANGE, menu_tool_change);
  321. #endif
  322. //
  323. // Set Case light on/off/brightness
  324. //
  325. #if ENABLED(CASE_LIGHT_MENU)
  326. #if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
  327. if (PWM_PIN(CASE_LIGHT_PIN))
  328. MENU_ITEM(submenu, MSG_CASE_LIGHT, menu_case_light);
  329. else
  330. #endif
  331. MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light);
  332. #endif
  333. #if HAS_LCD_CONTRAST
  334. MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, &ui.contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, ui.refresh_contrast, true);
  335. #endif
  336. #if ENABLED(FWRETRACT)
  337. MENU_ITEM(submenu, MSG_RETRACT, menu_config_retract);
  338. #endif
  339. #if HAS_FILAMENT_SENSOR
  340. MENU_ITEM_EDIT_CALLBACK(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset);
  341. #endif
  342. #if ENABLED(POWER_LOSS_RECOVERY)
  343. MENU_ITEM_EDIT_CALLBACK(bool, MSG_OUTAGE_RECOVERY, &recovery.enabled, recovery.changed);
  344. #endif
  345. #if DISABLED(SLIM_LCD_MENUS)
  346. // Preheat configurations
  347. MENU_ITEM(submenu, MSG_PREHEAT_1_SETTINGS, menu_preheat_material1_settings);
  348. MENU_ITEM(submenu, MSG_PREHEAT_2_SETTINGS, menu_preheat_material2_settings);
  349. #endif
  350. #if ENABLED(EEPROM_SETTINGS)
  351. MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings);
  352. if (!busy)
  353. MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings);
  354. #endif
  355. if (!busy)
  356. MENU_ITEM(function, MSG_RESTORE_FAILSAFE, lcd_factory_settings);
  357. END_MENU();
  358. }
  359. #endif // HAS_LCD_MENU