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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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. // Configuration Menu
  24. //
  25. #include "../../inc/MarlinConfigPre.h"
  26. #if HAS_LCD_MENU
  27. #include "menu.h"
  28. #if HAS_FILAMENT_SENSOR
  29. #include "../../feature/runout.h"
  30. #endif
  31. #if ENABLED(POWER_LOSS_RECOVERY)
  32. #include "../../feature/powerloss.h"
  33. #endif
  34. #if HAS_BED_PROBE
  35. #include "../../module/probe.h"
  36. #if ENABLED(BLTOUCH)
  37. #include "../../feature/bltouch.h"
  38. #endif
  39. #endif
  40. #define HAS_DEBUG_MENU ENABLED(LCD_PROGRESS_BAR_TEST)
  41. void menu_advanced_settings();
  42. #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION)
  43. void menu_delta_calibrate();
  44. #endif
  45. #if ENABLED(LCD_PROGRESS_BAR_TEST)
  46. #include "../lcdprint.h"
  47. static void progress_bar_test() {
  48. static int8_t bar_percent = 0;
  49. if (ui.use_click()) {
  50. ui.goto_previous_screen();
  51. ui.set_custom_characters(CHARSET_MENU);
  52. return;
  53. }
  54. bar_percent += (int8_t)ui.encoderPosition;
  55. LIMIT(bar_percent, 0, 100);
  56. ui.encoderPosition = 0;
  57. MenuItem_static::draw(0, GET_TEXT(MSG_PROGRESS_BAR_TEST), SS_CENTER|SS_INVERT);
  58. lcd_put_int((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2, bar_percent); lcd_put_wchar('%');
  59. lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent);
  60. }
  61. void _progress_bar_test() {
  62. ui.goto_screen(progress_bar_test);
  63. ui.set_custom_characters(CHARSET_INFO);
  64. }
  65. #endif // LCD_PROGRESS_BAR_TEST
  66. #if HAS_DEBUG_MENU
  67. void menu_debug() {
  68. START_MENU();
  69. BACK_ITEM(MSG_CONFIGURATION);
  70. #if ENABLED(LCD_PROGRESS_BAR_TEST)
  71. SUBMENU(MSG_PROGRESS_BAR_TEST, _progress_bar_test);
  72. #endif
  73. END_MENU();
  74. }
  75. #endif
  76. #if EXTRUDERS > 1
  77. #include "../../module/tool_change.h"
  78. void menu_tool_change() {
  79. START_MENU();
  80. BACK_ITEM(MSG_CONFIGURATION);
  81. #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
  82. static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500);
  83. #if ENABLED(TOOLCHANGE_PARK)
  84. EDIT_ITEM(bool, MSG_FILAMENT_PARK_ENABLED, &toolchange_settings.enable_park);
  85. #endif
  86. EDIT_ITEM(float3, MSG_FILAMENT_SWAP_LENGTH, &toolchange_settings.swap_length, 0, max_extrude);
  87. EDIT_ITEM(float41sign, MSG_FILAMENT_SWAP_EXTRA, &toolchange_settings.extra_resume, -10, 10);
  88. EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_RETRACT_SPEED, &toolchange_settings.retract_speed, 10, 5400);
  89. EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_UNRETRACT_SPEED, &toolchange_settings.unretract_speed, 10, 5400);
  90. EDIT_ITEM(float3, MSG_FILAMENT_PURGE_LENGTH, &toolchange_settings.extra_prime, 0, max_extrude);
  91. EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_PRIME_SPEED, &toolchange_settings.prime_speed, 10, 5400);
  92. EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255);
  93. EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30);
  94. #endif
  95. EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10);
  96. END_MENU();
  97. }
  98. #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
  99. #include "../../module/motion.h" // for active_extruder
  100. void menu_toolchange_migration() {
  101. PGM_P const msg_migrate = GET_TEXT(MSG_TOOL_MIGRATION_SWAP);
  102. START_MENU();
  103. BACK_ITEM(MSG_CONFIGURATION);
  104. // Auto mode ON/OFF
  105. EDIT_ITEM(bool, MSG_TOOL_MIGRATION_AUTO, &migration.automode);
  106. EDIT_ITEM(uint8, MSG_TOOL_MIGRATION_END, &migration.last, 0, EXTRUDERS - 1);
  107. // Migrate to a chosen extruder
  108. LOOP_L_N(s, EXTRUDERS) {
  109. if (s != active_extruder) {
  110. ACTION_ITEM_N_P(s, msg_migrate, []{
  111. char cmd[12];
  112. sprintf_P(cmd, PSTR("M217 T%i"), int(MenuItemBase::itemIndex));
  113. queue.inject(cmd);
  114. });
  115. }
  116. }
  117. END_MENU();
  118. }
  119. #endif
  120. #endif
  121. #if HAS_HOTEND_OFFSET
  122. #include "../../module/motion.h"
  123. #include "../../gcode/queue.h"
  124. void menu_tool_offsets() {
  125. auto _recalc_offsets = []{
  126. if (active_extruder && all_axes_known()) { // For the 2nd extruder re-home so the next tool-change gets the new offsets.
  127. queue.inject_P(G28_STR); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
  128. active_extruder = 0;
  129. }
  130. };
  131. START_MENU();
  132. BACK_ITEM(MSG_CONFIGURATION);
  133. #if ENABLED(DUAL_X_CARRIAGE)
  134. EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets);
  135. #else
  136. EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, -99.0, 99.0, _recalc_offsets);
  137. #endif
  138. EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Y, &hotend_offset[1].y, -99.0, 99.0, _recalc_offsets);
  139. EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Z, &hotend_offset[1].z, Z_PROBE_LOW_POINT, 10.0, _recalc_offsets);
  140. #if ENABLED(EEPROM_SETTINGS)
  141. ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings);
  142. #endif
  143. END_MENU();
  144. }
  145. #endif
  146. #if ENABLED(DUAL_X_CARRIAGE)
  147. void menu_idex() {
  148. const bool need_g28 = !(TEST(axis_known_position, Y_AXIS) && TEST(axis_known_position, Z_AXIS));
  149. START_MENU();
  150. BACK_ITEM(MSG_CONFIGURATION);
  151. GCODES_ITEM(MSG_IDEX_MODE_AUTOPARK, PSTR("M605 S1\nG28 X\nG1 X100"));
  152. GCODES_ITEM(MSG_IDEX_MODE_DUPLICATE, need_g28
  153. ? PSTR("M605 S1\nT0\nG28\nM605 S2 X200\nG28 X\nG1 X100") // If Y or Z is not homed, do a full G28 first
  154. : PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100")
  155. );
  156. GCODES_ITEM(MSG_IDEX_MODE_MIRRORED_COPY, need_g28
  157. ? 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
  158. : PSTR("M605 S1\nT0\nM605 S2 X200\nG28 X\nG1 X100\nM605 S3 X200")
  159. );
  160. GCODES_ITEM(MSG_IDEX_MODE_FULL_CTRL, PSTR("M605 S0\nG28 X"));
  161. END_MENU();
  162. }
  163. #endif
  164. #if ENABLED(BLTOUCH)
  165. #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU)
  166. void bltouch_report() {
  167. SERIAL_ECHOLNPAIR("EEPROM Last BLTouch Mode - ", (int)bltouch.last_written_mode);
  168. SERIAL_ECHOLNPGM("Configuration BLTouch Mode - " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD"));
  169. char mess[21];
  170. strcpy_P(mess, PSTR("BLTouch Mode - "));
  171. strcpy_P(&mess[15], bltouch.last_written_mode ? PSTR("5V") : PSTR("OD"));
  172. ui.set_status(mess);
  173. ui.return_to_status();
  174. }
  175. #endif
  176. void menu_bltouch() {
  177. START_MENU();
  178. BACK_ITEM(MSG_CONFIGURATION);
  179. ACTION_ITEM(MSG_BLTOUCH_RESET, bltouch._reset);
  180. ACTION_ITEM(MSG_BLTOUCH_SELFTEST, bltouch._selftest);
  181. ACTION_ITEM(MSG_BLTOUCH_DEPLOY, bltouch._deploy);
  182. ACTION_ITEM(MSG_BLTOUCH_STOW, bltouch._stow);
  183. ACTION_ITEM(MSG_BLTOUCH_SW_MODE, bltouch._set_SW_mode);
  184. #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU)
  185. CONFIRM_ITEM(MSG_BLTOUCH_5V_MODE, MSG_BLTOUCH_5V_MODE, MSG_BUTTON_CANCEL, bltouch._set_5V_mode, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE));
  186. CONFIRM_ITEM(MSG_BLTOUCH_OD_MODE, MSG_BLTOUCH_OD_MODE, MSG_BUTTON_CANCEL, bltouch._set_OD_mode, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE));
  187. ACTION_ITEM(MSG_BLTOUCH_MODE_STORE, bltouch._mode_store);
  188. CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_5V, MSG_BLTOUCH_MODE_STORE_5V, MSG_BUTTON_CANCEL, bltouch.mode_conv_5V, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE));
  189. CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_OD, MSG_BLTOUCH_MODE_STORE_OD, MSG_BUTTON_CANCEL, bltouch.mode_conv_OD, ui.goto_previous_screen, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE));
  190. ACTION_ITEM(MSG_BLTOUCH_MODE_ECHO, bltouch_report);
  191. #endif
  192. END_MENU();
  193. }
  194. #endif
  195. #if ENABLED(TOUCH_MI_PROBE)
  196. void menu_touchmi() {
  197. ui.defer_status_screen();
  198. START_MENU();
  199. BACK_ITEM(MSG_CONFIGURATION);
  200. GCODES_ITEM(MSG_TOUCHMI_INIT, PSTR("M851 Z0\nG28\nG1 F200 Z0"));
  201. SUBMENU(MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset);
  202. GCODES_ITEM(MSG_TOUCHMI_SAVE, PSTR("M500\nG1 F200 Z10"));
  203. GCODES_ITEM(MSG_TOUCHMI_ZTEST, PSTR("G28\nG1 F200 Z0"));
  204. END_MENU();
  205. }
  206. #endif
  207. #if ENABLED(CONTROLLER_FAN_MENU)
  208. #include "../../feature/controllerfan.h"
  209. void menu_controller_fan() {
  210. START_MENU();
  211. BACK_ITEM(MSG_CONFIGURATION);
  212. EDIT_ITEM_FAST(percent, MSG_CONTROLLER_FAN_IDLE_SPEED, &controllerFan.settings.idle_speed, _MAX(1, CONTROLLERFAN_SPEED_MIN) - 1, 255);
  213. EDIT_ITEM(bool, MSG_CONTROLLER_FAN_AUTO_ON, &controllerFan.settings.auto_mode);
  214. if (controllerFan.settings.auto_mode) {
  215. EDIT_ITEM_FAST(percent, MSG_CONTROLLER_FAN_SPEED, &controllerFan.settings.active_speed, _MAX(1, CONTROLLERFAN_SPEED_MIN) - 1, 255);
  216. EDIT_ITEM(uint16_4, MSG_CONTROLLER_FAN_DURATION, &controllerFan.settings.duration, 0, 4800);
  217. }
  218. END_MENU();
  219. }
  220. #endif
  221. #if ENABLED(FWRETRACT)
  222. #include "../../feature/fwretract.h"
  223. void menu_config_retract() {
  224. START_MENU();
  225. BACK_ITEM(MSG_CONFIGURATION);
  226. #if ENABLED(FWRETRACT_AUTORETRACT)
  227. EDIT_ITEM(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled, fwretract.refresh_autoretract);
  228. #endif
  229. EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT, &fwretract.settings.retract_length, 0, 100);
  230. #if EXTRUDERS > 1
  231. EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_SWAP, &fwretract.settings.swap_retract_length, 0, 100);
  232. #endif
  233. EDIT_ITEM(float3, MSG_CONTROL_RETRACTF, &fwretract.settings.retract_feedrate_mm_s, 1, 999);
  234. EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_ZHOP, &fwretract.settings.retract_zraise, 0, 999);
  235. EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_RECOVER, &fwretract.settings.retract_recover_extra, -100, 100);
  236. #if EXTRUDERS > 1
  237. EDIT_ITEM(float52sign, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.settings.swap_retract_recover_extra, -100, 100);
  238. #endif
  239. EDIT_ITEM(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.settings.retract_recover_feedrate_mm_s, 1, 999);
  240. #if EXTRUDERS > 1
  241. EDIT_ITEM(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.settings.swap_retract_recover_feedrate_mm_s, 1, 999);
  242. #endif
  243. END_MENU();
  244. }
  245. #endif
  246. #if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS)
  247. void _menu_configuration_preheat_settings() {
  248. #define _MINTEMP_ITEM(N) HEATER_##N##_MINTEMP,
  249. #define _MAXTEMP_ITEM(N) HEATER_##N##_MAXTEMP,
  250. #define MINTEMP_ALL _MIN(REPEAT(HOTENDS, _MINTEMP_ITEM) 999)
  251. #define MAXTEMP_ALL _MAX(REPEAT(HOTENDS, _MAXTEMP_ITEM) 0)
  252. const uint8_t m = MenuItemBase::itemIndex;
  253. START_MENU();
  254. BACK_ITEM(MSG_CONFIGURATION);
  255. #if HAS_FAN
  256. editable.uint8 = uint8_t(ui.material_preset[m].fan_speed);
  257. EDIT_ITEM_N(percent, m, MSG_FAN_SPEED, &editable.uint8, 0, 255, []{ ui.material_preset[MenuItemBase::itemIndex].fan_speed = editable.uint8; });
  258. #endif
  259. #if HAS_TEMP_HOTEND
  260. EDIT_ITEM(uint16_3, MSG_NOZZLE, &ui.material_preset[m].hotend_temp, MINTEMP_ALL, MAXTEMP_ALL - HOTEND_OVERSHOOT);
  261. #endif
  262. #if HAS_HEATED_BED
  263. EDIT_ITEM(uint16_3, MSG_BED, &ui.material_preset[m].bed_temp, BED_MINTEMP, BED_MAX_TARGET);
  264. #endif
  265. #if ENABLED(EEPROM_SETTINGS)
  266. ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings);
  267. #endif
  268. END_MENU();
  269. }
  270. #endif
  271. void menu_configuration() {
  272. const bool busy = printer_busy();
  273. START_MENU();
  274. BACK_ITEM(MSG_MAIN);
  275. //
  276. // Debug Menu when certain options are enabled
  277. //
  278. #if HAS_DEBUG_MENU
  279. SUBMENU(MSG_DEBUG_MENU, menu_debug);
  280. #endif
  281. SUBMENU(MSG_ADVANCED_SETTINGS, menu_advanced_settings);
  282. #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
  283. SUBMENU(MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset);
  284. #elif HAS_BED_PROBE
  285. EDIT_ITEM(LCD_Z_OFFSET_TYPE, MSG_ZPROBE_ZOFFSET, &probe.offset.z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX);
  286. #endif
  287. //
  288. // Set Fan Controller speed
  289. //
  290. #if ENABLED(CONTROLLER_FAN_MENU)
  291. SUBMENU(MSG_CONTROLLER_FAN, menu_controller_fan);
  292. #endif
  293. if (!busy) {
  294. #if EITHER(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION)
  295. SUBMENU(MSG_DELTA_CALIBRATE, menu_delta_calibrate);
  296. #endif
  297. #if HAS_HOTEND_OFFSET
  298. SUBMENU(MSG_OFFSETS_MENU, menu_tool_offsets);
  299. #endif
  300. #if ENABLED(DUAL_X_CARRIAGE)
  301. SUBMENU(MSG_IDEX_MENU, menu_idex);
  302. #endif
  303. #if ENABLED(BLTOUCH)
  304. SUBMENU(MSG_BLTOUCH, menu_bltouch);
  305. #endif
  306. #if ENABLED(TOUCH_MI_PROBE)
  307. SUBMENU(MSG_TOUCHMI_PROBE, menu_touchmi);
  308. #endif
  309. }
  310. //
  311. // Set single nozzle filament retract and prime length
  312. //
  313. #if EXTRUDERS > 1
  314. SUBMENU(MSG_TOOL_CHANGE, menu_tool_change);
  315. #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
  316. SUBMENU(MSG_TOOL_MIGRATION, menu_toolchange_migration);
  317. #endif
  318. #endif
  319. #if HAS_LCD_CONTRAST
  320. EDIT_ITEM(int3, MSG_CONTRAST, &ui.contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, ui.refresh_contrast, true);
  321. #endif
  322. #if ENABLED(FWRETRACT)
  323. SUBMENU(MSG_RETRACT, menu_config_retract);
  324. #endif
  325. #if HAS_FILAMENT_SENSOR
  326. EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset);
  327. #endif
  328. #if ENABLED(POWER_LOSS_RECOVERY)
  329. EDIT_ITEM(bool, MSG_OUTAGE_RECOVERY, &recovery.enabled, recovery.changed);
  330. #endif
  331. // Preheat configurations
  332. #if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS)
  333. LOOP_L_N(m, PREHEAT_COUNT)
  334. SUBMENU_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings);
  335. #endif
  336. #if ENABLED(EEPROM_SETTINGS)
  337. ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings);
  338. if (!busy) ACTION_ITEM(MSG_LOAD_EEPROM, ui.load_settings);
  339. #endif
  340. if (!busy) ACTION_ITEM(MSG_RESTORE_DEFAULTS, ui.reset_settings);
  341. END_MENU();
  342. }
  343. #endif // HAS_LCD_MENU