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.

M240.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. #include "../../../inc/MarlinConfig.h"
  23. #if ENABLED(PHOTO_GCODE)
  24. #include "../../gcode.h"
  25. #include "../../../module/motion.h" // for active_extruder and current_position
  26. #if PIN_EXISTS(CHDK)
  27. millis_t chdk_timeout; // = 0
  28. #endif
  29. #if defined(PHOTO_POSITION) && PHOTO_DELAY_MS > 0
  30. #include "../../../MarlinCore.h" // for idle()
  31. #endif
  32. #ifdef PHOTO_RETRACT_MM
  33. #define _PHOTO_RETRACT_MM (PHOTO_RETRACT_MM + 0)
  34. #include "../../../module/planner.h"
  35. #include "../../../module/temperature.h"
  36. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  37. #include "../../../feature/pause.h"
  38. #endif
  39. #ifdef PHOTO_RETRACT_MM
  40. inline void e_move_m240(const float length, const feedRate_t &fr_mm_s) {
  41. if (length && thermalManager.hotEnoughToExtrude(active_extruder)) {
  42. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  43. do_pause_e_move(length, fr_mm_s);
  44. #else
  45. current_position.e += length / planner.e_factor[active_extruder];
  46. line_to_current_position(fr_mm_s);
  47. #endif
  48. }
  49. }
  50. #endif
  51. #endif
  52. #if PIN_EXISTS(PHOTOGRAPH)
  53. FORCE_INLINE void set_photo_pin(const uint8_t state) {
  54. constexpr uint32_t pulse_length = (
  55. #ifdef PHOTO_PULSES_US
  56. PHOTO_PULSE_DELAY_US
  57. #else
  58. 15 // 15.24 from _delay_ms(0.01524)
  59. #endif
  60. );
  61. WRITE(PHOTOGRAPH_PIN, state);
  62. delayMicroseconds(pulse_length);
  63. }
  64. FORCE_INLINE void tweak_photo_pin() { set_photo_pin(HIGH); set_photo_pin(LOW); }
  65. #ifdef PHOTO_PULSES_US
  66. inline void pulse_photo_pin(const uint32_t duration, const uint8_t state) {
  67. if (state) {
  68. for (const uint32_t stop = micros() + duration; micros() < stop;)
  69. tweak_photo_pin();
  70. }
  71. else
  72. delayMicroseconds(duration);
  73. }
  74. inline void spin_photo_pin() {
  75. static constexpr uint32_t sequence[] = PHOTO_PULSES_US;
  76. LOOP_L_N(i, COUNT(sequence))
  77. pulse_photo_pin(sequence[i], !(i & 1));
  78. }
  79. #else
  80. constexpr uint8_t NUM_PULSES = 16;
  81. inline void spin_photo_pin() { for (uint8_t i = NUM_PULSES; i--;) tweak_photo_pin(); }
  82. #endif
  83. #endif
  84. /**
  85. * M240: Trigger a camera by...
  86. *
  87. * - CHDK : Emulate a Canon RC-1 with a configurable ON duration.
  88. * http://captain-slow.dk/2014/03/09/3d-printing-timelapses/
  89. * - PHOTOGRAPH_PIN : Pulse a digital pin 16 times.
  90. * See http://www.doc-diy.net/photo/rc-1_hacked/
  91. * - PHOTO_SWITCH_POSITION : Bump a physical switch with the X-carriage using a
  92. * configured position, delay, and retract length.
  93. *
  94. * PHOTO_POSITION parameters:
  95. * A - X offset to the return position
  96. * B - Y offset to the return position
  97. * F - Override the XY movement feedrate
  98. * R - Retract/recover length (current units)
  99. * S - Retract/recover feedrate (mm/m)
  100. * X - Move to X before triggering the shutter
  101. * Y - Move to Y before triggering the shutter
  102. * Z - Raise Z by a distance before triggering the shutter
  103. *
  104. * PHOTO_SWITCH_POSITION parameters:
  105. * D - Duration (ms) to hold down switch (Requires PHOTO_SWITCH_MS)
  106. * P - Delay (ms) after triggering the shutter (Requires PHOTO_SWITCH_MS)
  107. * I - Switch trigger position override X
  108. * J - Switch trigger position override Y
  109. */
  110. void GcodeSuite::M240() {
  111. #ifdef PHOTO_POSITION
  112. if (axis_unhomed_error()) return;
  113. const xyz_pos_t old_pos = {
  114. current_position.x + parser.linearval('A'),
  115. current_position.y + parser.linearval('B'),
  116. current_position.z
  117. };
  118. #ifdef PHOTO_RETRACT_MM
  119. const float rval = parser.seenval('R') ? parser.value_linear_units() : _PHOTO_RETRACT_MM;
  120. feedRate_t sval = (
  121. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  122. PAUSE_PARK_RETRACT_FEEDRATE
  123. #elif ENABLED(FWRETRACT)
  124. RETRACT_FEEDRATE
  125. #else
  126. 45
  127. #endif
  128. );
  129. if (parser.seenval('S')) sval = parser.value_feedrate();
  130. e_move_m240(-rval, sval);
  131. #endif
  132. feedRate_t fr_mm_s = MMM_TO_MMS(parser.linearval('F'));
  133. if (fr_mm_s) NOLESS(fr_mm_s, 10.0f);
  134. constexpr xyz_pos_t photo_position = PHOTO_POSITION;
  135. xyz_pos_t raw = {
  136. parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : photo_position.x,
  137. parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_position.y,
  138. (parser.seenval('Z') ? parser.value_linear_units() : photo_position.z) + current_position.z
  139. };
  140. apply_motion_limits(raw);
  141. do_blocking_move_to(raw, fr_mm_s);
  142. #ifdef PHOTO_SWITCH_POSITION
  143. constexpr xy_pos_t photo_switch_position = PHOTO_SWITCH_POSITION;
  144. const xy_pos_t sraw = {
  145. parser.seenval('I') ? RAW_X_POSITION(parser.value_linear_units()) : photo_switch_position.x,
  146. parser.seenval('J') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_switch_position.y
  147. };
  148. do_blocking_move_to_xy(sraw, get_homing_bump_feedrate(X_AXIS));
  149. #if PHOTO_SWITCH_MS > 0
  150. safe_delay(parser.intval('D', PHOTO_SWITCH_MS));
  151. #endif
  152. do_blocking_move_to(raw);
  153. #endif
  154. #endif
  155. #if PIN_EXISTS(CHDK)
  156. OUT_WRITE(CHDK_PIN, HIGH);
  157. chdk_timeout = millis() + parser.intval('D', PHOTO_SWITCH_MS);
  158. #elif HAS_PHOTOGRAPH
  159. spin_photo_pin();
  160. delay(7.33);
  161. spin_photo_pin();
  162. #endif
  163. #ifdef PHOTO_POSITION
  164. #if PHOTO_DELAY_MS > 0
  165. const millis_t timeout = millis() + parser.intval('P', PHOTO_DELAY_MS);
  166. while (PENDING(millis(), timeout)) idle();
  167. #endif
  168. do_blocking_move_to(old_pos, fr_mm_s);
  169. #ifdef PHOTO_RETRACT_MM
  170. e_move_m240(rval, sval);
  171. #endif
  172. #endif
  173. }
  174. #endif // PHOTO_GCODE