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.

probe.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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. /**
  23. * probe.cpp
  24. */
  25. #include "../inc/MarlinConfig.h"
  26. #if HAS_BED_PROBE
  27. #include "probe.h"
  28. #include "motion.h"
  29. #include "temperature.h"
  30. #include "endstops.h"
  31. #include "../gcode/gcode.h"
  32. #include "../lcd/ultralcd.h"
  33. #include "../Marlin.h"
  34. #if HAS_LEVELING
  35. #include "../feature/bedlevel/bedlevel.h"
  36. #endif
  37. #if ENABLED(DELTA)
  38. #include "../module/delta.h"
  39. #endif
  40. #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
  41. #include "planner.h"
  42. #endif
  43. float zprobe_zoffset; // Initialized by settings.load()
  44. #if HAS_Z_SERVO_ENDSTOP
  45. const int z_servo_angle[2] = Z_SERVO_ANGLES;
  46. #endif
  47. /**
  48. * Raise Z to a minimum height to make room for a probe to move
  49. */
  50. inline void do_probe_raise(const float z_raise) {
  51. #if ENABLED(DEBUG_LEVELING_FEATURE)
  52. if (DEBUGGING(LEVELING)) {
  53. SERIAL_ECHOPAIR("do_probe_raise(", z_raise);
  54. SERIAL_CHAR(')');
  55. SERIAL_EOL();
  56. }
  57. #endif
  58. float z_dest = z_raise;
  59. if (zprobe_zoffset < 0) z_dest -= zprobe_zoffset;
  60. if (z_dest > current_position[Z_AXIS])
  61. do_blocking_move_to_z(z_dest);
  62. }
  63. #if ENABLED(Z_PROBE_SLED)
  64. #ifndef SLED_DOCKING_OFFSET
  65. #define SLED_DOCKING_OFFSET 0
  66. #endif
  67. /**
  68. * Method to dock/undock a sled designed by Charles Bell.
  69. *
  70. * stow[in] If false, move to MAX_X and engage the solenoid
  71. * If true, move to MAX_X and release the solenoid
  72. */
  73. static void dock_sled(bool stow) {
  74. #if ENABLED(DEBUG_LEVELING_FEATURE)
  75. if (DEBUGGING(LEVELING)) {
  76. SERIAL_ECHOPAIR("dock_sled(", stow);
  77. SERIAL_CHAR(')');
  78. SERIAL_EOL();
  79. }
  80. #endif
  81. // Dock sled a bit closer to ensure proper capturing
  82. do_blocking_move_to_x(X_MAX_POS + SLED_DOCKING_OFFSET - ((stow) ? 1 : 0));
  83. #if HAS_SOLENOID_1 && DISABLED(EXT_SOLENOID)
  84. WRITE(SOL1_PIN, !stow); // switch solenoid
  85. #endif
  86. }
  87. #elif ENABLED(Z_PROBE_ALLEN_KEY)
  88. FORCE_INLINE void do_blocking_move_to(const float logical[XYZ], const float &fr_mm_s) {
  89. do_blocking_move_to(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS], fr_mm_s);
  90. }
  91. void run_deploy_moves_script() {
  92. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Z)
  93. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_X
  94. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X current_position[X_AXIS]
  95. #endif
  96. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Y
  97. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y current_position[Y_AXIS]
  98. #endif
  99. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Z
  100. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z current_position[Z_AXIS]
  101. #endif
  102. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE
  103. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0
  104. #endif
  105. const float deploy_1[] = { Z_PROBE_ALLEN_KEY_DEPLOY_1_X, Z_PROBE_ALLEN_KEY_DEPLOY_1_Y, Z_PROBE_ALLEN_KEY_DEPLOY_1_Z };
  106. do_blocking_move_to(deploy_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE));
  107. #endif
  108. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Z)
  109. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_X
  110. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X current_position[X_AXIS]
  111. #endif
  112. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Y
  113. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y current_position[Y_AXIS]
  114. #endif
  115. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Z
  116. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z current_position[Z_AXIS]
  117. #endif
  118. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE
  119. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0
  120. #endif
  121. const float deploy_2[] = { Z_PROBE_ALLEN_KEY_DEPLOY_2_X, Z_PROBE_ALLEN_KEY_DEPLOY_2_Y, Z_PROBE_ALLEN_KEY_DEPLOY_2_Z };
  122. do_blocking_move_to(deploy_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE));
  123. #endif
  124. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Z)
  125. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_X
  126. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X current_position[X_AXIS]
  127. #endif
  128. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Y
  129. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y current_position[Y_AXIS]
  130. #endif
  131. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Z
  132. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z current_position[Z_AXIS]
  133. #endif
  134. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE
  135. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0
  136. #endif
  137. const float deploy_3[] = { Z_PROBE_ALLEN_KEY_DEPLOY_3_X, Z_PROBE_ALLEN_KEY_DEPLOY_3_Y, Z_PROBE_ALLEN_KEY_DEPLOY_3_Z };
  138. do_blocking_move_to(deploy_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE));
  139. #endif
  140. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Z)
  141. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_X
  142. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_X current_position[X_AXIS]
  143. #endif
  144. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Y
  145. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Y current_position[Y_AXIS]
  146. #endif
  147. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Z
  148. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Z current_position[Z_AXIS]
  149. #endif
  150. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE
  151. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0
  152. #endif
  153. const float deploy_4[] = { Z_PROBE_ALLEN_KEY_DEPLOY_4_X, Z_PROBE_ALLEN_KEY_DEPLOY_4_Y, Z_PROBE_ALLEN_KEY_DEPLOY_4_Z };
  154. do_blocking_move_to(deploy_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE));
  155. #endif
  156. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Z)
  157. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_X
  158. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_X current_position[X_AXIS]
  159. #endif
  160. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Y
  161. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Y current_position[Y_AXIS]
  162. #endif
  163. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Z
  164. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Z current_position[Z_AXIS]
  165. #endif
  166. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE
  167. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0
  168. #endif
  169. const float deploy_5[] = { Z_PROBE_ALLEN_KEY_DEPLOY_5_X, Z_PROBE_ALLEN_KEY_DEPLOY_5_Y, Z_PROBE_ALLEN_KEY_DEPLOY_5_Z };
  170. do_blocking_move_to(deploy_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE));
  171. #endif
  172. }
  173. void run_stow_moves_script() {
  174. #if defined(Z_PROBE_ALLEN_KEY_STOW_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Z)
  175. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_X
  176. #define Z_PROBE_ALLEN_KEY_STOW_1_X current_position[X_AXIS]
  177. #endif
  178. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Y
  179. #define Z_PROBE_ALLEN_KEY_STOW_1_Y current_position[Y_AXIS]
  180. #endif
  181. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Z
  182. #define Z_PROBE_ALLEN_KEY_STOW_1_Z current_position[Z_AXIS]
  183. #endif
  184. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE
  185. #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0
  186. #endif
  187. const float stow_1[] = { Z_PROBE_ALLEN_KEY_STOW_1_X, Z_PROBE_ALLEN_KEY_STOW_1_Y, Z_PROBE_ALLEN_KEY_STOW_1_Z };
  188. do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE));
  189. #endif
  190. #if defined(Z_PROBE_ALLEN_KEY_STOW_2_X) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Z)
  191. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_X
  192. #define Z_PROBE_ALLEN_KEY_STOW_2_X current_position[X_AXIS]
  193. #endif
  194. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Y
  195. #define Z_PROBE_ALLEN_KEY_STOW_2_Y current_position[Y_AXIS]
  196. #endif
  197. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Z
  198. #define Z_PROBE_ALLEN_KEY_STOW_2_Z current_position[Z_AXIS]
  199. #endif
  200. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE
  201. #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0
  202. #endif
  203. const float stow_2[] = { Z_PROBE_ALLEN_KEY_STOW_2_X, Z_PROBE_ALLEN_KEY_STOW_2_Y, Z_PROBE_ALLEN_KEY_STOW_2_Z };
  204. do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE));
  205. #endif
  206. #if defined(Z_PROBE_ALLEN_KEY_STOW_3_X) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Z)
  207. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_X
  208. #define Z_PROBE_ALLEN_KEY_STOW_3_X current_position[X_AXIS]
  209. #endif
  210. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Y
  211. #define Z_PROBE_ALLEN_KEY_STOW_3_Y current_position[Y_AXIS]
  212. #endif
  213. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Z
  214. #define Z_PROBE_ALLEN_KEY_STOW_3_Z current_position[Z_AXIS]
  215. #endif
  216. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE
  217. #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0
  218. #endif
  219. const float stow_3[] = { Z_PROBE_ALLEN_KEY_STOW_3_X, Z_PROBE_ALLEN_KEY_STOW_3_Y, Z_PROBE_ALLEN_KEY_STOW_3_Z };
  220. do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE));
  221. #endif
  222. #if defined(Z_PROBE_ALLEN_KEY_STOW_4_X) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Z)
  223. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_X
  224. #define Z_PROBE_ALLEN_KEY_STOW_4_X current_position[X_AXIS]
  225. #endif
  226. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Y
  227. #define Z_PROBE_ALLEN_KEY_STOW_4_Y current_position[Y_AXIS]
  228. #endif
  229. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Z
  230. #define Z_PROBE_ALLEN_KEY_STOW_4_Z current_position[Z_AXIS]
  231. #endif
  232. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE
  233. #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0
  234. #endif
  235. const float stow_4[] = { Z_PROBE_ALLEN_KEY_STOW_4_X, Z_PROBE_ALLEN_KEY_STOW_4_Y, Z_PROBE_ALLEN_KEY_STOW_4_Z };
  236. do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE));
  237. #endif
  238. #if defined(Z_PROBE_ALLEN_KEY_STOW_5_X) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Z)
  239. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_X
  240. #define Z_PROBE_ALLEN_KEY_STOW_5_X current_position[X_AXIS]
  241. #endif
  242. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Y
  243. #define Z_PROBE_ALLEN_KEY_STOW_5_Y current_position[Y_AXIS]
  244. #endif
  245. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Z
  246. #define Z_PROBE_ALLEN_KEY_STOW_5_Z current_position[Z_AXIS]
  247. #endif
  248. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE
  249. #define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0
  250. #endif
  251. const float stow_5[] = { Z_PROBE_ALLEN_KEY_STOW_5_X, Z_PROBE_ALLEN_KEY_STOW_5_Y, Z_PROBE_ALLEN_KEY_STOW_5_Z };
  252. do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE));
  253. #endif
  254. }
  255. #endif // Z_PROBE_ALLEN_KEY
  256. #if ENABLED(PROBING_FANS_OFF)
  257. void fans_pause(const bool p) {
  258. if (p != fans_paused) {
  259. fans_paused = p;
  260. if (p)
  261. for (uint8_t x = 0; x < FAN_COUNT; x++) {
  262. paused_fanSpeeds[x] = fanSpeeds[x];
  263. fanSpeeds[x] = 0;
  264. }
  265. else
  266. for (uint8_t x = 0; x < FAN_COUNT; x++)
  267. fanSpeeds[x] = paused_fanSpeeds[x];
  268. }
  269. }
  270. #endif // PROBING_FANS_OFF
  271. #if QUIET_PROBING
  272. void probing_pause(const bool p) {
  273. #if ENABLED(PROBING_HEATERS_OFF)
  274. thermalManager.pause(p);
  275. #endif
  276. #if ENABLED(PROBING_FANS_OFF)
  277. fans_pause(p);
  278. #endif
  279. if (p) safe_delay(
  280. #if DELAY_BEFORE_PROBING > 25
  281. DELAY_BEFORE_PROBING
  282. #else
  283. 25
  284. #endif
  285. );
  286. }
  287. #endif // QUIET_PROBING
  288. #if ENABLED(BLTOUCH)
  289. void bltouch_command(const int angle) {
  290. MOVE_SERVO(Z_ENDSTOP_SERVO_NR, angle); // Give the BL-Touch the command and wait
  291. safe_delay(BLTOUCH_DELAY);
  292. }
  293. bool set_bltouch_deployed(const bool deploy) {
  294. if (deploy && TEST_BLTOUCH()) { // If BL-Touch says it's triggered
  295. bltouch_command(BLTOUCH_RESET); // try to reset it.
  296. bltouch_command(BLTOUCH_DEPLOY); // Also needs to deploy and stow to
  297. bltouch_command(BLTOUCH_STOW); // clear the triggered condition.
  298. safe_delay(1500); // Wait for internal self-test to complete.
  299. // (Measured completion time was 0.65 seconds
  300. // after reset, deploy, and stow sequence)
  301. if (TEST_BLTOUCH()) { // If it still claims to be triggered...
  302. SERIAL_ERROR_START();
  303. SERIAL_ERRORLNPGM(MSG_STOP_BLTOUCH);
  304. stop(); // punt!
  305. return true;
  306. }
  307. }
  308. bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
  309. #if ENABLED(DEBUG_LEVELING_FEATURE)
  310. if (DEBUGGING(LEVELING)) {
  311. SERIAL_ECHOPAIR("set_bltouch_deployed(", deploy);
  312. SERIAL_CHAR(')');
  313. SERIAL_EOL();
  314. }
  315. #endif
  316. return false;
  317. }
  318. #endif // BLTOUCH
  319. // returns false for ok and true for failure
  320. bool set_probe_deployed(const bool deploy) {
  321. // Can be extended to servo probes, if needed.
  322. #if ENABLED(PROBE_IS_TRIGGERED_WHEN_STOWED_TEST)
  323. #if ENABLED(Z_MIN_PROBE_ENDSTOP)
  324. #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
  325. #else
  326. #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
  327. #endif
  328. #endif
  329. #if ENABLED(DEBUG_LEVELING_FEATURE)
  330. if (DEBUGGING(LEVELING)) {
  331. DEBUG_POS("set_probe_deployed", current_position);
  332. SERIAL_ECHOLNPAIR("deploy: ", deploy);
  333. }
  334. #endif
  335. if (endstops.z_probe_enabled == deploy) return false;
  336. // Make room for probe
  337. do_probe_raise(_Z_CLEARANCE_DEPLOY_PROBE);
  338. #if ENABLED(Z_PROBE_SLED) || ENABLED(Z_PROBE_ALLEN_KEY)
  339. #if ENABLED(Z_PROBE_SLED)
  340. #define _AUE_ARGS true, false, false
  341. #else
  342. #define _AUE_ARGS
  343. #endif
  344. if (axis_unhomed_error(_AUE_ARGS)) {
  345. SERIAL_ERROR_START();
  346. SERIAL_ERRORLNPGM(MSG_STOP_UNHOMED);
  347. stop();
  348. return true;
  349. }
  350. #endif
  351. const float oldXpos = current_position[X_AXIS],
  352. oldYpos = current_position[Y_AXIS];
  353. #ifdef _TRIGGERED_WHEN_STOWED_TEST
  354. // If endstop is already false, the Z probe is deployed
  355. if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // closed after the probe specific actions.
  356. // Would a goto be less ugly?
  357. //while (!_TRIGGERED_WHEN_STOWED_TEST) idle(); // would offer the opportunity
  358. // for a triggered when stowed manual probe.
  359. if (!deploy) endstops.enable_z_probe(false); // Switch off triggered when stowed probes early
  360. // otherwise an Allen-Key probe can't be stowed.
  361. #endif
  362. #if ENABLED(SOLENOID_PROBE)
  363. #if HAS_SOLENOID_1
  364. WRITE(SOL1_PIN, deploy);
  365. #endif
  366. #elif ENABLED(Z_PROBE_SLED)
  367. dock_sled(!deploy);
  368. #elif HAS_Z_SERVO_ENDSTOP && DISABLED(BLTOUCH)
  369. MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[deploy ? 0 : 1]);
  370. #elif ENABLED(Z_PROBE_ALLEN_KEY)
  371. deploy ? run_deploy_moves_script() : run_stow_moves_script();
  372. #endif
  373. #ifdef _TRIGGERED_WHEN_STOWED_TEST
  374. } // _TRIGGERED_WHEN_STOWED_TEST == deploy
  375. if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // State hasn't changed?
  376. if (IsRunning()) {
  377. SERIAL_ERROR_START();
  378. SERIAL_ERRORLNPGM("Z-Probe failed");
  379. LCD_ALERTMESSAGEPGM("Err: ZPROBE");
  380. }
  381. stop();
  382. return true;
  383. } // _TRIGGERED_WHEN_STOWED_TEST == deploy
  384. #endif
  385. do_blocking_move_to(oldXpos, oldYpos, current_position[Z_AXIS]); // return to position before deploy
  386. endstops.enable_z_probe(deploy);
  387. return false;
  388. }
  389. /**
  390. * @brief Used by run_z_probe to do a single Z probe move.
  391. *
  392. * @param z Z destination
  393. * @param fr_mm_s Feedrate in mm/s
  394. * @return true to indicate an error
  395. */
  396. static bool do_probe_move(const float z, const float fr_mm_m) {
  397. #if ENABLED(DEBUG_LEVELING_FEATURE)
  398. if (DEBUGGING(LEVELING)) DEBUG_POS(">>> do_probe_move", current_position);
  399. #endif
  400. // Deploy BLTouch at the start of any probe
  401. #if ENABLED(BLTOUCH)
  402. if (set_bltouch_deployed(true)) return true;
  403. #endif
  404. #if QUIET_PROBING
  405. probing_pause(true);
  406. #endif
  407. // Move down until probe triggered
  408. do_blocking_move_to_z(z, MMM_TO_MMS(fr_mm_m));
  409. // Check to see if the probe was triggered
  410. const bool probe_triggered = TEST(Endstops::endstop_hit_bits,
  411. #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
  412. Z_MIN
  413. #else
  414. Z_MIN_PROBE
  415. #endif
  416. );
  417. #if QUIET_PROBING
  418. probing_pause(false);
  419. #endif
  420. // Retract BLTouch immediately after a probe if it was triggered
  421. #if ENABLED(BLTOUCH)
  422. if (probe_triggered && set_bltouch_deployed(false)) return true;
  423. #endif
  424. // Clear endstop flags
  425. endstops.hit_on_purpose();
  426. // Get Z where the steppers were interrupted
  427. set_current_from_steppers_for_axis(Z_AXIS);
  428. // Tell the planner where we actually are
  429. SYNC_PLAN_POSITION_KINEMATIC();
  430. #if ENABLED(DEBUG_LEVELING_FEATURE)
  431. if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position);
  432. #endif
  433. return !probe_triggered;
  434. }
  435. /**
  436. * @details Used by probe_pt to do a single Z probe.
  437. * Leaves current_position[Z_AXIS] at the height where the probe triggered.
  438. *
  439. * @param short_move Flag for a shorter probe move towards the bed
  440. * @return The raw Z position where the probe was triggered
  441. */
  442. static float run_z_probe(const bool short_move=true) {
  443. #if ENABLED(DEBUG_LEVELING_FEATURE)
  444. if (DEBUGGING(LEVELING)) DEBUG_POS(">>> run_z_probe", current_position);
  445. #endif
  446. // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding
  447. gcode.refresh_cmd_timeout();
  448. #if ENABLED(PROBE_DOUBLE_TOUCH)
  449. // Do a first probe at the fast speed
  450. if (do_probe_move(-10, Z_PROBE_SPEED_FAST)) return NAN;
  451. #if ENABLED(DEBUG_LEVELING_FEATURE)
  452. float first_probe_z = current_position[Z_AXIS];
  453. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("1st Probe Z:", first_probe_z);
  454. #endif
  455. // move up to make clearance for the probe
  456. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  457. #else
  458. // If the nozzle is above the travel height then
  459. // move down quickly before doing the slow probe
  460. float z = Z_CLEARANCE_DEPLOY_PROBE;
  461. if (zprobe_zoffset < 0) z -= zprobe_zoffset;
  462. if (z < current_position[Z_AXIS]) {
  463. // If we don't make it to the z position (i.e. the probe triggered), move up to make clearance for the probe
  464. if (!do_probe_move(z, Z_PROBE_SPEED_FAST))
  465. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  466. }
  467. #endif
  468. // move down slowly to find bed
  469. if (do_probe_move(-10 + (short_move ? 0 : -(Z_MAX_LENGTH)), Z_PROBE_SPEED_SLOW)) return NAN;
  470. #if ENABLED(DEBUG_LEVELING_FEATURE)
  471. if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position);
  472. #endif
  473. // Debug: compare probe heights
  474. #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE)
  475. if (DEBUGGING(LEVELING)) {
  476. SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]);
  477. SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]);
  478. }
  479. #endif
  480. return RAW_CURRENT_POSITION(Z) + zprobe_zoffset
  481. #if ENABLED(DELTA)
  482. + home_offset[Z_AXIS] // Account for delta height adjustment
  483. #endif
  484. ;
  485. }
  486. /**
  487. * - Move to the given XY
  488. * - Deploy the probe, if not already deployed
  489. * - Probe the bed, get the Z position
  490. * - Depending on the 'stow' flag
  491. * - Stow the probe, or
  492. * - Raise to the BETWEEN height
  493. * - Return the probed Z position
  494. */
  495. float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable/*=true*/) {
  496. #if ENABLED(DEBUG_LEVELING_FEATURE)
  497. if (DEBUGGING(LEVELING)) {
  498. SERIAL_ECHOPAIR(">>> probe_pt(", lx);
  499. SERIAL_ECHOPAIR(", ", ly);
  500. SERIAL_ECHOPAIR(", ", stow ? "" : "no ");
  501. SERIAL_ECHOLNPGM("stow)");
  502. DEBUG_POS("", current_position);
  503. }
  504. #endif
  505. const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER);
  506. if (printable
  507. ? !position_is_reachable_xy(nx, ny)
  508. : !position_is_reachable_by_probe_xy(lx, ly)
  509. ) return NAN;
  510. const float old_feedrate_mm_s = feedrate_mm_s;
  511. #if ENABLED(DELTA)
  512. if (current_position[Z_AXIS] > delta_clip_start_height)
  513. do_blocking_move_to_z(delta_clip_start_height);
  514. #endif
  515. #if HAS_SOFTWARE_ENDSTOPS
  516. // Store the status of the soft endstops and disable if we're probing a non-printable location
  517. static bool enable_soft_endstops = soft_endstops_enabled;
  518. if (!printable) soft_endstops_enabled = false;
  519. #endif
  520. feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S;
  521. // Move the probe to the given XY
  522. do_blocking_move_to_xy(nx, ny);
  523. float measured_z = NAN;
  524. if (!DEPLOY_PROBE()) {
  525. measured_z = run_z_probe(printable);
  526. if (!stow)
  527. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  528. else
  529. if (STOW_PROBE()) measured_z = NAN;
  530. }
  531. #if HAS_SOFTWARE_ENDSTOPS
  532. // Restore the soft endstop status
  533. soft_endstops_enabled = enable_soft_endstops;
  534. #endif
  535. if (verbose_level > 2) {
  536. SERIAL_PROTOCOLPGM("Bed X: ");
  537. SERIAL_PROTOCOL_F(lx, 3);
  538. SERIAL_PROTOCOLPGM(" Y: ");
  539. SERIAL_PROTOCOL_F(ly, 3);
  540. SERIAL_PROTOCOLPGM(" Z: ");
  541. SERIAL_PROTOCOL_F(measured_z, 3);
  542. SERIAL_EOL();
  543. }
  544. #if ENABLED(DEBUG_LEVELING_FEATURE)
  545. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt");
  546. #endif
  547. feedrate_mm_s = old_feedrate_mm_s;
  548. if (isnan(measured_z)) {
  549. LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED);
  550. SERIAL_ERROR_START();
  551. SERIAL_ERRORLNPGM(MSG_ERR_PROBING_FAILED);
  552. }
  553. return measured_z;
  554. }
  555. void refresh_zprobe_zoffset(const bool no_babystep/*=false*/) {
  556. static float last_zoffset = NAN;
  557. if (!isnan(last_zoffset)) {
  558. #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(BABYSTEP_ZPROBE_OFFSET) || ENABLED(DELTA)
  559. const float diff = zprobe_zoffset - last_zoffset;
  560. #endif
  561. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  562. // Correct bilinear grid for new probe offset
  563. if (diff) {
  564. for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
  565. for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
  566. z_values[x][y] -= diff;
  567. }
  568. #if ENABLED(ABL_BILINEAR_SUBDIVISION)
  569. bed_level_virt_interpolate();
  570. #endif
  571. #endif
  572. #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
  573. if (!no_babystep && planner.leveling_active)
  574. thermalManager.babystep_axis(Z_AXIS, -LROUND(diff * planner.axis_steps_per_mm[Z_AXIS]));
  575. #else
  576. UNUSED(no_babystep);
  577. #endif
  578. #if ENABLED(DELTA) // correct the delta_height
  579. home_offset[Z_AXIS] -= diff;
  580. #endif
  581. }
  582. last_zoffset = zprobe_zoffset;
  583. }
  584. #if HAS_Z_SERVO_ENDSTOP
  585. void servo_probe_init() {
  586. /**
  587. * Set position of Z Servo Endstop
  588. *
  589. * The servo might be deployed and positioned too low to stow
  590. * when starting up the machine or rebooting the board.
  591. * There's no way to know where the nozzle is positioned until
  592. * homing has been done - no homing with z-probe without init!
  593. *
  594. */
  595. STOW_Z_SERVO();
  596. }
  597. #endif // HAS_Z_SERVO_ENDSTOP
  598. #endif // HAS_BED_PROBE