first_lay_cal.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //! @file
  2. //! @date Jun 10, 2019
  3. //! @author Marek Bel
  4. //! @brief First layer (Z offset) calibration
  5. #include "first_lay_cal.h"
  6. #include "Configuration_var.h"
  7. #include "language.h"
  8. #include "Marlin.h"
  9. #include "cmdqueue.h"
  10. #include "mmu2.h"
  11. #include <avr/pgmspace.h>
  12. //! @brief Wait for preheat
  13. void lay1cal_wait_preheat()
  14. {
  15. const char * const preheat_cmd[] =
  16. {
  17. PSTR("M107"),
  18. PSTR("M190"),
  19. PSTR("M109"),
  20. PSTR("G28"),
  21. PSTR("G92 E0.0")
  22. };
  23. for (uint8_t i = 0; i < (sizeof(preheat_cmd)/sizeof(preheat_cmd[0])); ++i)
  24. {
  25. enquecommand_P(preheat_cmd[i]);
  26. }
  27. }
  28. //! @brief Load filament
  29. //! @param cmd_buffer character buffer needed to format gcodes
  30. //! @param filament filament to use (applies for MMU only)
  31. //! @returns true if extra purge distance is needed in case of MMU prints (after a toolchange), otherwise false
  32. bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
  33. {
  34. if (MMU2::mmu2.Enabled())
  35. {
  36. enquecommand_P(PSTR("M83"));
  37. enquecommand_P(PSTR("G1 Y-3.0 F1000.0"));
  38. enquecommand_P(PSTR("G1 Z0.4 F1000.0"));
  39. uint8_t currentTool = MMU2::mmu2.get_current_tool();
  40. if(currentTool == filament ){
  41. // already have the correct tool loaded - do nothing
  42. return false;
  43. } else if( currentTool != (uint8_t)MMU2::FILAMENT_UNKNOWN){
  44. // some other slot is loaded, perform an unload first
  45. enquecommand_P(PSTR("M702"));
  46. }
  47. // perform a toolchange
  48. // sprintf_P(cmd_buffer, PSTR("T%d"), filament);
  49. // rewriting the trivial T<filament> g-code command saves 30B:
  50. cmd_buffer[0] = 'T';
  51. cmd_buffer[1] = filament + '0';
  52. cmd_buffer[2] = 0;
  53. enquecommand(cmd_buffer);
  54. return true;
  55. }
  56. return false;
  57. }
  58. //! @brief Print intro line
  59. //! @param extraPurgeNeeded false if the first MMU-related "G1 E29" have to be skipped because the nozzle is already full of filament
  60. void lay1cal_intro_line(bool extraPurgeNeeded)
  61. {
  62. static const char cmd_intro_mmu_3[] PROGMEM = "G1 X55.0 E29.0 F1073.0";
  63. static const char cmd_intro_mmu_4[] PROGMEM = "G1 X5.0 E29.0 F1800.0";
  64. static const char cmd_intro_mmu_5[] PROGMEM = "G1 X55.0 E8.0 F2000.0";
  65. static const char cmd_intro_mmu_6[] PROGMEM = "G1 Z0.3 F1000.0";
  66. static const char cmd_intro_mmu_7[] PROGMEM = "G92 E0.0";
  67. static const char cmd_intro_mmu_8[] PROGMEM = "G1 X240.0 E25.0 F2200.0";
  68. static const char cmd_intro_mmu_9[] PROGMEM = "G1 Y-2.0 F1000.0";
  69. static const char cmd_intro_mmu_10[] PROGMEM = "G1 X55.0 E25 F1400.0";
  70. static const char cmd_intro_mmu_11[] PROGMEM = "G1 Z0.20 F1000.0";
  71. static const char cmd_intro_mmu_12[] PROGMEM = "G1 X5.0 E4.0 F1000.0";
  72. static const char * const intro_mmu_cmd[] PROGMEM =
  73. {
  74. // first 2 items are only relevant if filament was not loaded - i.e. extraPurgeNeeded == true
  75. cmd_intro_mmu_3,
  76. cmd_intro_mmu_4,
  77. cmd_intro_mmu_5,
  78. cmd_intro_mmu_6,
  79. cmd_intro_mmu_7,
  80. cmd_intro_mmu_8,
  81. cmd_intro_mmu_9,
  82. cmd_intro_mmu_10,
  83. cmd_intro_mmu_11,
  84. cmd_intro_mmu_12,
  85. };
  86. if (MMU2::mmu2.Enabled())
  87. {
  88. for (uint8_t i = (extraPurgeNeeded ? 0 : 2); i < (sizeof(intro_mmu_cmd)/sizeof(intro_mmu_cmd[0])); ++i)
  89. {
  90. enquecommand_P(static_cast<char*>(pgm_read_ptr(&intro_mmu_cmd[i])));
  91. }
  92. }
  93. else
  94. {
  95. enquecommand_P(PSTR("G1 X60.0 E9.0 F1000.0"));
  96. enquecommand_P(PSTR("G1 X100.0 E12.5 F1000.0"));
  97. }
  98. }
  99. //! @brief Setup for printing meander
  100. void lay1cal_before_meander()
  101. {
  102. static const char cmd_pre_meander_0[] PROGMEM = "G92 E0.0";
  103. static const char cmd_pre_meander_1[] PROGMEM = "G21"; //set units to millimeters TODO unsupported command
  104. static const char cmd_pre_meander_2[] PROGMEM = "G90"; //use absolute coordinates
  105. static const char cmd_pre_meander_3[] PROGMEM = "M83"; //use relative distances for extrusion TODO: duplicate
  106. static const char cmd_pre_meander_4[] PROGMEM = "G1 E-1.50000 F2100.00000";
  107. static const char cmd_pre_meander_5[] PROGMEM = "G1 Z5 F7200.000";
  108. static const char cmd_pre_meander_6[] PROGMEM = "M204 S1000"; //set acceleration
  109. static const char cmd_pre_meander_7[] PROGMEM = "G1 F4000";
  110. static const char * const cmd_pre_meander[] PROGMEM =
  111. {
  112. cmd_pre_meander_0,
  113. cmd_pre_meander_1,
  114. cmd_pre_meander_2,
  115. cmd_pre_meander_3,
  116. cmd_pre_meander_4,
  117. cmd_pre_meander_5,
  118. cmd_pre_meander_6,
  119. cmd_pre_meander_7,
  120. };
  121. for (uint8_t i = 0; i < (sizeof(cmd_pre_meander)/sizeof(cmd_pre_meander[0])); ++i)
  122. {
  123. enquecommand_P(static_cast<char*>(pgm_read_ptr(&cmd_pre_meander[i])));
  124. }
  125. }
  126. //! @brief Count extrude length
  127. //!
  128. //! @param layer_height layer height in mm
  129. //! @param extrusion_width extrusion width in mm
  130. //! @param extrusion_length extrusion length in mm
  131. //! @return filament length in mm which needs to be extruded to form line
  132. static constexpr float count_e(float layer_height, float extrusion_width, float extrusion_length)
  133. {
  134. return (extrusion_length * layer_height * extrusion_width / (M_PI * pow(1.75, 2) / 4));
  135. }
  136. static const float width = 0.4; //!< line width
  137. static const float length = 20 - width; //!< line length
  138. static const float height = 0.2; //!< layer height TODO This is wrong, as current Z height is 0.15 mm
  139. static const float extr = count_e(height, width, length); //!< E axis movement needed to print line
  140. //! @brief Print meander
  141. //! @param cmd_buffer character buffer needed to format gcodes
  142. void lay1cal_meander(char *cmd_buffer)
  143. {
  144. static const char cmd_meander_0[] PROGMEM = "G1 X50 Y155";
  145. static const char cmd_meander_1[] PROGMEM = "G1 Z0.150 F7200.000";
  146. static const char cmd_meander_2[] PROGMEM = "G1 F1080";
  147. static const char cmd_meander_3[] PROGMEM = "G1 X75 Y155 E2.5";
  148. static const char cmd_meander_4[] PROGMEM = "G1 X100 Y155 E2";
  149. static const char cmd_meander_5[] PROGMEM = "G1 X200 Y155 E2.62773";
  150. static const char cmd_meander_6[] PROGMEM = "G1 X200 Y135 E0.66174";
  151. static const char cmd_meander_7[] PROGMEM = "G1 X50 Y135 E3.62773";
  152. static const char cmd_meander_8[] PROGMEM = "G1 X50 Y115 E0.49386";
  153. static const char cmd_meander_9[] PROGMEM = "G1 X200 Y115 E3.62773";
  154. static const char cmd_meander_10[] PROGMEM = "G1 X200 Y95 E0.49386";
  155. static const char cmd_meander_11[] PROGMEM = "G1 X50 Y95 E3.62773";
  156. static const char cmd_meander_12[] PROGMEM = "G1 X50 Y75 E0.49386";
  157. static const char cmd_meander_13[] PROGMEM = "G1 X200 Y75 E3.62773";
  158. static const char cmd_meander_14[] PROGMEM = "G1 X200 Y55 E0.49386";
  159. static const char cmd_meander_15[] PROGMEM = "G1 X50 Y55 E3.62773";
  160. static const char * const cmd_meander[] PROGMEM =
  161. {
  162. cmd_meander_0,
  163. cmd_meander_1,
  164. cmd_meander_2,
  165. cmd_meander_3,
  166. cmd_meander_4,
  167. cmd_meander_5,
  168. cmd_meander_6,
  169. cmd_meander_7,
  170. cmd_meander_8,
  171. cmd_meander_9,
  172. cmd_meander_10,
  173. cmd_meander_11,
  174. cmd_meander_12,
  175. cmd_meander_13,
  176. cmd_meander_14,
  177. cmd_meander_15,
  178. };
  179. for (uint8_t i = 0; i < (sizeof(cmd_meander)/sizeof(cmd_meander[0])); ++i)
  180. {
  181. enquecommand_P(static_cast<char*>(pgm_read_ptr(&cmd_meander[i])));
  182. }
  183. sprintf_P(cmd_buffer, PSTR("G1 X50 Y35 E%-.3f"), extr);
  184. enquecommand(cmd_buffer);
  185. }
  186. //! @brief Print square
  187. //!
  188. //! This function needs to be called 16 times for i from 0 to 15.
  189. //!
  190. //! @param cmd_buffer character buffer needed to format gcodes
  191. //! @param i iteration
  192. void lay1cal_square(char *cmd_buffer, uint8_t i)
  193. {
  194. const float extr_short_segment = count_e(height, width, width);
  195. static const char fmt1[] PROGMEM = "G1 X%d Y%-.2f E%-.3f";
  196. static const char fmt2[] PROGMEM = "G1 Y%-.2f E%-.3f";
  197. sprintf_P(cmd_buffer, fmt1, 70, (35 - i*width * 2), extr);
  198. enquecommand(cmd_buffer);
  199. sprintf_P(cmd_buffer, fmt2, (35 - (2 * i + 1)*width), extr_short_segment);
  200. enquecommand(cmd_buffer);
  201. sprintf_P(cmd_buffer, fmt1, 50, (35 - (2 * i + 1)*width), extr);
  202. enquecommand(cmd_buffer);
  203. sprintf_P(cmd_buffer, fmt2, (35 - (i + 1)*width * 2), extr_short_segment);
  204. enquecommand(cmd_buffer);
  205. }