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.

ubl.cpp 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. #include "Marlin.h"
  23. #include "math.h"
  24. #if ENABLED(AUTO_BED_LEVELING_UBL)
  25. #include "ubl.h"
  26. #include "hex_print_routines.h"
  27. #include "temperature.h"
  28. #include "planner.h"
  29. uint8_t ubl_cnt = 0;
  30. void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); }
  31. void unified_bed_leveling::report_state() {
  32. echo_name();
  33. SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " ");
  34. if (!planner.leveling_active) SERIAL_PROTOCOLPGM("in");
  35. SERIAL_PROTOCOLLNPGM("active.");
  36. safe_delay(50);
  37. }
  38. static void serial_echo_xy(const int16_t x, const int16_t y) {
  39. SERIAL_CHAR('(');
  40. SERIAL_ECHO(x);
  41. SERIAL_CHAR(',');
  42. SERIAL_ECHO(y);
  43. SERIAL_CHAR(')');
  44. safe_delay(10);
  45. }
  46. #if ENABLED(UBL_DEVEL_DEBUGGING)
  47. static void debug_echo_axis(const AxisEnum axis) {
  48. if (current_position[axis] == destination[axis])
  49. SERIAL_ECHOPGM("-------------");
  50. else
  51. SERIAL_ECHO_F(destination[X_AXIS], 6);
  52. }
  53. void debug_current_and_destination(const char *title) {
  54. // if the title message starts with a '!' it is so important, we are going to
  55. // ignore the status of the g26_debug_flag
  56. if (*title != '!' && !g26_debug_flag) return;
  57. const float de = destination[E_AXIS] - current_position[E_AXIS];
  58. if (de == 0.0) return; // Printing moves only
  59. const float dx = destination[X_AXIS] - current_position[X_AXIS],
  60. dy = destination[Y_AXIS] - current_position[Y_AXIS],
  61. xy_dist = HYPOT(dx, dy);
  62. if (xy_dist == 0.0) return;
  63. SERIAL_ECHOPGM(" fpmm=");
  64. const float fpmm = de / xy_dist;
  65. SERIAL_ECHO_F(fpmm, 6);
  66. SERIAL_ECHOPGM(" current=( ");
  67. SERIAL_ECHO_F(current_position[X_AXIS], 6);
  68. SERIAL_ECHOPGM(", ");
  69. SERIAL_ECHO_F(current_position[Y_AXIS], 6);
  70. SERIAL_ECHOPGM(", ");
  71. SERIAL_ECHO_F(current_position[Z_AXIS], 6);
  72. SERIAL_ECHOPGM(", ");
  73. SERIAL_ECHO_F(current_position[E_AXIS], 6);
  74. SERIAL_ECHOPGM(" ) destination=( ");
  75. debug_echo_axis(X_AXIS);
  76. SERIAL_ECHOPGM(", ");
  77. debug_echo_axis(Y_AXIS);
  78. SERIAL_ECHOPGM(", ");
  79. debug_echo_axis(Z_AXIS);
  80. SERIAL_ECHOPGM(", ");
  81. debug_echo_axis(E_AXIS);
  82. SERIAL_ECHOPGM(" ) ");
  83. SERIAL_ECHO(title);
  84. SERIAL_EOL();
  85. }
  86. #endif // UBL_DEVEL_DEBUGGING
  87. int8_t unified_bed_leveling::storage_slot;
  88. float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
  89. // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
  90. // until determinism prevails
  91. constexpr float unified_bed_leveling::_mesh_index_to_xpos[16],
  92. unified_bed_leveling::_mesh_index_to_ypos[16];
  93. #if ENABLED(ULTIPANEL)
  94. bool unified_bed_leveling::lcd_map_control = false;
  95. #endif
  96. volatile int unified_bed_leveling::encoder_diff;
  97. unified_bed_leveling::unified_bed_leveling() {
  98. ubl_cnt++; // Debug counter to ensure we only have one UBL object present in memory. We can eliminate this (and all references to ubl_cnt) very soon.
  99. reset();
  100. }
  101. void unified_bed_leveling::reset() {
  102. const bool was_enabled = planner.leveling_active;
  103. set_bed_leveling_enabled(false);
  104. storage_slot = -1;
  105. #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
  106. planner.set_z_fade_height(10.0);
  107. #endif
  108. ZERO(z_values);
  109. if (was_enabled) report_current_position();
  110. }
  111. void unified_bed_leveling::invalidate() {
  112. set_bed_leveling_enabled(false);
  113. set_all_mesh_points_to_value(NAN);
  114. }
  115. void unified_bed_leveling::set_all_mesh_points_to_value(const float value) {
  116. for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) {
  117. for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) {
  118. z_values[x][y] = value;
  119. }
  120. }
  121. }
  122. // display_map() currently produces three different mesh map types
  123. // 0 : suitable for PronterFace and Repetier's serial console
  124. // 1 : .CSV file suitable for importation into various spread sheets
  125. // 2 : disply of the map data on a RepRap Graphical LCD Panel
  126. void unified_bed_leveling::display_map(const int map_type) {
  127. constexpr uint8_t spaces = 8 * (GRID_MAX_POINTS_X - 2);
  128. SERIAL_PROTOCOLPGM("\nBed Topography Report");
  129. if (map_type == 0) {
  130. SERIAL_PROTOCOLPGM(":\n\n");
  131. serial_echo_xy(0, GRID_MAX_POINTS_Y - 1);
  132. SERIAL_ECHO_SP(spaces + 3);
  133. serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1);
  134. SERIAL_EOL();
  135. serial_echo_xy(MESH_MIN_X, MESH_MAX_Y);
  136. SERIAL_ECHO_SP(spaces);
  137. serial_echo_xy(MESH_MAX_X, MESH_MAX_Y);
  138. SERIAL_EOL();
  139. }
  140. else {
  141. SERIAL_PROTOCOLPGM(" for ");
  142. serialprintPGM(map_type == 1 ? PSTR("CSV:\n\n") : PSTR("LCD:\n\n"));
  143. }
  144. const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
  145. current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
  146. for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
  147. for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
  148. const bool is_current = i == current_xi && j == current_yi;
  149. // is the nozzle here? then mark the number
  150. if (map_type == 0) SERIAL_CHAR(is_current ? '[' : ' ');
  151. const float f = z_values[i][j];
  152. if (isnan(f)) {
  153. serialprintPGM(map_type == 0 ? PSTR(" . ") : PSTR("NAN"));
  154. }
  155. else if (map_type <= 1) {
  156. // if we don't do this, the columns won't line up nicely
  157. if (map_type == 0 && f >= 0.0) SERIAL_CHAR(' ');
  158. SERIAL_PROTOCOL_F(f, 3);
  159. }
  160. idle();
  161. if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(',');
  162. #if TX_BUFFER_SIZE > 0
  163. MYSERIAL.flushTX();
  164. #endif
  165. safe_delay(15);
  166. if (map_type == 0) {
  167. SERIAL_CHAR(is_current ? ']' : ' ');
  168. SERIAL_CHAR(' ');
  169. }
  170. }
  171. SERIAL_EOL();
  172. if (j && map_type == 0) { // we want the (0,0) up tight against the block of numbers
  173. SERIAL_CHAR(' ');
  174. SERIAL_EOL();
  175. }
  176. }
  177. if (map_type == 0) {
  178. serial_echo_xy(MESH_MIN_X, MESH_MIN_Y);
  179. SERIAL_ECHO_SP(spaces + 4);
  180. serial_echo_xy(MESH_MAX_X, MESH_MIN_Y);
  181. SERIAL_EOL();
  182. serial_echo_xy(0, 0);
  183. SERIAL_ECHO_SP(spaces + 5);
  184. serial_echo_xy(GRID_MAX_POINTS_X - 1, 0);
  185. SERIAL_EOL();
  186. }
  187. }
  188. bool unified_bed_leveling::sanity_check() {
  189. uint8_t error_flag = 0;
  190. if (settings.calc_num_meshes() < 1) {
  191. SERIAL_PROTOCOLLNPGM("?Mesh too big for EEPROM.");
  192. error_flag++;
  193. }
  194. return !!error_flag;
  195. }
  196. #endif // AUTO_BED_LEVELING_UBL