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 22KB

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