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

draw_z_offset_wizard.cpp 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2022 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 <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "../../../inc/MarlinConfigPre.h"
  23. #if BOTH(HAS_TFT_LVGL_UI, PROBE_OFFSET_WIZARD)
  24. #include "draw_ui.h"
  25. #include <lv_conf.h>
  26. #include "../../../gcode/queue.h"
  27. #include "../../../module/motion.h"
  28. #include "../../../module/planner.h"
  29. #include "../../../inc/MarlinConfig.h"
  30. #include "../../../module/probe.h"
  31. #if HAS_LEVELING
  32. #include "../../../feature/bedlevel/bedlevel.h"
  33. bool leveling_was_active;
  34. #endif
  35. extern lv_group_t *g;
  36. static lv_obj_t *scr;
  37. static lv_obj_t *labelV, *buttonV, *labelP;
  38. static lv_obj_t *labelP_z_offset_ref;
  39. static lv_task_t *updatePosTask;
  40. static char cur_label = 'Z';
  41. static float cur_pos = 0;
  42. static float cur_OffsetPos = 0;
  43. // Global storage
  44. float z_offset_backup, calculated_z_offset, z_offset_ref;
  45. enum {
  46. ID_M_Z_P = 1,
  47. ID_M_Z_N,
  48. ID_M_STEP,
  49. ID_M_SAVE,
  50. ID_M_RETURN
  51. };
  52. void disp_cur_wizard_pos() {
  53. char str_1[18];
  54. sprintf_P(public_buf_l, PSTR("%c:%s mm"), cur_label, dtostrf(cur_pos, 1, 3, str_1));
  55. if (labelP) lv_label_set_text(labelP, public_buf_l);
  56. sprintf_P(public_buf_l, PSTR("%c Offset:%s mm"), cur_label, dtostrf(cur_OffsetPos, 1, 3, str_1));
  57. if (labelP_z_offset_ref) lv_label_set_text(labelP_z_offset_ref, public_buf_l);
  58. }
  59. static void event_handler(lv_obj_t *obj, lv_event_t event) {
  60. char str_1[16];
  61. if (event != LV_EVENT_RELEASED) return;
  62. //lv_clear_z_offset_wizard();
  63. if (!queue.ring_buffer.full(3)) {
  64. bool do_inject = true;
  65. float dist = uiCfg.move_dist;
  66. switch (obj->mks_obj_id) {
  67. case ID_M_Z_N: dist *= -1; case ID_M_Z_P: cur_label = 'Z'; break;
  68. default: do_inject = false;
  69. }
  70. if (do_inject) {
  71. sprintf_P(public_buf_l, PSTR("G91\nG1 %c%s F%d\nG90"), cur_label, dtostrf(dist, 1, 3, str_1), uiCfg.moveSpeed);
  72. queue.inject(public_buf_l);
  73. //calculated_z_offset = probe.offset.z + current_position.z - z_offset_ref;
  74. disp_cur_wizard_pos();
  75. }
  76. }
  77. switch (obj->mks_obj_id) {
  78. case ID_M_STEP:
  79. if (ABS((int)(10 * uiCfg.move_dist)) == 10)
  80. uiCfg.move_dist = 0.025;
  81. else if (ABS((int)(1000 * uiCfg.move_dist)) == 25)
  82. uiCfg.move_dist = 0.1;
  83. else
  84. uiCfg.move_dist *= 10.0f;
  85. disp_move_wizard_dist();
  86. break;
  87. case ID_M_SAVE:
  88. current_position.z = z_offset_ref; // Set Z to z_offset_ref, as we can expect it is at probe height
  89. probe.offset.z = calculated_z_offset;
  90. sync_plan_position();
  91. // Raise Z as if it was homed
  92. do_z_clearance(Z_POST_CLEARANCE);
  93. hal.watchdog_refresh();
  94. draw_return_ui();
  95. return;
  96. case ID_M_RETURN:
  97. probe.offset.z = z_offset_backup;
  98. SET_SOFT_ENDSTOP_LOOSE(false);
  99. TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active));
  100. #if HOMING_Z_WITH_PROBE && defined(PROBE_OFFSET_WIZARD_START_Z)
  101. set_axis_never_homed(Z_AXIS); // On cancel the Z position needs correction
  102. queue.inject_P(PSTR("G28Z"));
  103. #else // Otherwise do a Z clearance move like after Homing
  104. do_z_clearance(Z_POST_CLEARANCE);
  105. #endif
  106. hal.watchdog_refresh();
  107. draw_return_ui();
  108. return;
  109. }
  110. disp_cur_wizard_pos();
  111. }
  112. void refresh_wizard_pos(lv_task_t *) {
  113. switch (cur_label) {
  114. case 'Z':
  115. cur_pos = current_position.z;
  116. calculated_z_offset = probe.offset.z + current_position.z - z_offset_ref;
  117. cur_OffsetPos = calculated_z_offset;
  118. break;
  119. default: return;
  120. }
  121. disp_cur_wizard_pos();
  122. }
  123. void lv_draw_z_offset_wizard() {
  124. set_all_unhomed();
  125. // Store probe.offset.z for Case: Cancel
  126. z_offset_backup = probe.offset.z;
  127. #ifdef PROBE_OFFSET_WIZARD_START_Z
  128. probe.offset.z = PROBE_OFFSET_WIZARD_START_Z;
  129. #endif
  130. // Store Bed-Leveling-State and disable
  131. #if HAS_LEVELING
  132. leveling_was_active = planner.leveling_active;
  133. set_bed_leveling_enabled(leveling_was_active);
  134. #endif
  135. queue.inject_P(PSTR("G28"));
  136. z_offset_ref = 0; // Set Z Value for Wizard Position to 0
  137. calculated_z_offset = probe.offset.z + current_position.z - z_offset_ref;
  138. cur_OffsetPos = calculated_z_offset;
  139. scr = lv_screen_create(Z_OFFSET_WIZARD_UI, machine_menu.LevelingZoffsetTitle);
  140. lv_obj_t *buttonXI = lv_big_button_create(scr, "F:/bmp_zAdd.bin", move_menu.z_add, INTERVAL_V, titleHeight, event_handler, ID_M_Z_P);
  141. lv_obj_clear_protect(buttonXI, LV_PROTECT_FOLLOW);
  142. lv_big_button_create(scr, "F:/bmp_zDec.bin", move_menu.z_dec, INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_Z_N);
  143. // button with image and label changed dynamically by disp_move_dist
  144. buttonV = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_M_STEP);
  145. labelV = lv_label_create_empty(buttonV);
  146. #if HAS_ROTARY_ENCODER
  147. if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonV);
  148. #endif
  149. // save and back
  150. lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_save, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_SAVE);
  151. // cancel and back
  152. lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_RETURN);
  153. // We need to patch the title to leave some space on the right for displaying the status
  154. lv_obj_t * z_offset_ref_title = lv_obj_get_child_back(scr, nullptr);
  155. if (z_offset_ref_title != nullptr) lv_obj_set_width(z_offset_ref_title, (int)(TFT_WIDTH / 2) - 101);
  156. labelP_z_offset_ref = lv_label_create(scr, (int)(TFT_WIDTH / 2) - 80, (int)(TFT_HEIGHT/2)-20, "Z Offset:0.0mm");
  157. // We need to patch the Z Offset to leave some space in the middle for displaying the status
  158. lv_obj_t * title= lv_obj_get_child_back(scr, nullptr);
  159. if (title != nullptr) lv_obj_set_width(title, TFT_WIDTH - 101);
  160. labelP = lv_label_create(scr, TFT_WIDTH - 100, TITLE_YPOS, "Z:0.0mm");
  161. if (labelP != nullptr)
  162. updatePosTask = lv_task_create(refresh_wizard_pos, 300, LV_TASK_PRIO_LOWEST, 0);
  163. disp_move_wizard_dist();
  164. disp_cur_wizard_pos();
  165. }
  166. void disp_move_wizard_dist() {
  167. if ((int)(1000 * uiCfg.move_dist) == 25)
  168. lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move0_1.bin");
  169. else if ((int)(10 * uiCfg.move_dist) == 1)
  170. lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move1.bin");
  171. else if ((int)(10 * uiCfg.move_dist) == 10)
  172. lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move10.bin");
  173. if (gCfgItems.multiple_language) {
  174. if ((int)(1000 * uiCfg.move_dist) == 25) {
  175. lv_label_set_text(labelV, move_menu.step_0025mm);
  176. lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
  177. }
  178. else if ((int)(10 * uiCfg.move_dist) == 1) {
  179. lv_label_set_text(labelV, move_menu.step_01mm);
  180. lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
  181. }
  182. else if ((int)(10 * uiCfg.move_dist) == 10) {
  183. lv_label_set_text(labelV, move_menu.step_1mm);
  184. lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
  185. }
  186. }
  187. }
  188. void lv_clear_z_offset_wizard() {
  189. #if HAS_ROTARY_ENCODER
  190. if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
  191. #endif
  192. lv_obj_del(scr);
  193. }
  194. #endif // HAS_TFT_LVGL_UI && PROBE_OFFSET_WIZARD