mmu.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //mmu.cpp
  2. #include "mmu.h"
  3. #include "planner.h"
  4. #include "language.h"
  5. #include "lcd.h"
  6. #include "uart2.h"
  7. #include "temperature.h"
  8. #include "Configuration_prusa.h"
  9. extern const char* lcd_display_message_fullscreen_P(const char *msg);
  10. extern void lcd_return_to_status();
  11. #ifdef SNMM_V2
  12. bool mmu_enabled = true;
  13. #else //SNMM_V2
  14. bool mmu_enabled = false;
  15. #endif //SNMM_V2
  16. uint8_t snmm_extruder = 0;
  17. void extr_mov(float shift, float feed_rate)
  18. { //move extruder no matter what the current heater temperature is
  19. set_extrude_min_temp(.0);
  20. current_position[E_AXIS] += shift;
  21. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feed_rate, active_extruder);
  22. set_extrude_min_temp(EXTRUDE_MINTEMP);
  23. }
  24. void change_extr(int extr) { //switches multiplexer for extruders
  25. #ifdef SNMM
  26. st_synchronize();
  27. delay(100);
  28. disable_e0();
  29. disable_e1();
  30. disable_e2();
  31. snmm_extruder = extr;
  32. pinMode(E_MUX0_PIN, OUTPUT);
  33. pinMode(E_MUX1_PIN, OUTPUT);
  34. switch (extr) {
  35. case 1:
  36. WRITE(E_MUX0_PIN, HIGH);
  37. WRITE(E_MUX1_PIN, LOW);
  38. break;
  39. case 2:
  40. WRITE(E_MUX0_PIN, LOW);
  41. WRITE(E_MUX1_PIN, HIGH);
  42. break;
  43. case 3:
  44. WRITE(E_MUX0_PIN, HIGH);
  45. WRITE(E_MUX1_PIN, HIGH);
  46. break;
  47. default:
  48. WRITE(E_MUX0_PIN, LOW);
  49. WRITE(E_MUX1_PIN, LOW);
  50. break;
  51. }
  52. delay(100);
  53. #endif
  54. }
  55. int get_ext_nr()
  56. { //reads multiplexer input pins and return current extruder number (counted from 0)
  57. #ifndef SNMM
  58. return(snmm_extruder); //update needed
  59. #else
  60. return(2 * READ(E_MUX1_PIN) + READ(E_MUX0_PIN));
  61. #endif
  62. }
  63. void display_loading()
  64. {
  65. switch (snmm_extruder)
  66. {
  67. case 1: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T1)); break;
  68. case 2: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T2)); break;
  69. case 3: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T3)); break;
  70. default: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T0)); break;
  71. }
  72. }
  73. void extr_adj(int extruder) //loading filament for SNMM
  74. {
  75. #ifndef SNMM
  76. printf_P(PSTR("L%d \n"),extruder);
  77. fprintf_P(uart2io, PSTR("L%d\n"), extruder);
  78. //show which filament is currently loaded
  79. lcd_update_enable(false);
  80. lcd_clear();
  81. lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_LOADING_FILAMENT));
  82. //if(strlen(_T(MSG_LOADING_FILAMENT))>18) lcd.setCursor(0, 1);
  83. //else lcd.print(" ");
  84. lcd_print(" ");
  85. lcd_print(snmm_extruder + 1);
  86. // get response
  87. manage_response();
  88. lcd_update_enable(true);
  89. //lcd_return_to_status();
  90. #else
  91. bool correct;
  92. max_feedrate[E_AXIS] =80;
  93. //max_feedrate[E_AXIS] = 50;
  94. START:
  95. lcd_clear();
  96. lcd_set_cursor(0, 0);
  97. switch (extruder) {
  98. case 1: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T1)); break;
  99. case 2: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T2)); break;
  100. case 3: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T3)); break;
  101. default: lcd_display_message_fullscreen_P(_T(MSG_FILAMENT_LOADING_T0)); break;
  102. }
  103. KEEPALIVE_STATE(PAUSED_FOR_USER);
  104. do{
  105. extr_mov(0.001,1000);
  106. delay_keep_alive(2);
  107. } while (!lcd_clicked());
  108. //delay_keep_alive(500);
  109. KEEPALIVE_STATE(IN_HANDLER);
  110. st_synchronize();
  111. //correct = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_FIL_LOADED_CHECK, false);
  112. //if (!correct) goto START;
  113. //extr_mov(BOWDEN_LENGTH/2.f, 500); //dividing by 2 is there because of max. extrusion length limitation (x_max + y_max)
  114. //extr_mov(BOWDEN_LENGTH/2.f, 500);
  115. extr_mov(bowden_length[extruder], 500);
  116. lcd_clear();
  117. lcd_set_cursor(0, 0); lcd_puts_P(_T(MSG_LOADING_FILAMENT));
  118. if(strlen(_T(MSG_LOADING_FILAMENT))>18) lcd_set_cursor(0, 1);
  119. else lcd_print(" ");
  120. lcd_print(snmm_extruder + 1);
  121. lcd_set_cursor(0, 2); lcd_puts_P(_T(MSG_PLEASE_WAIT));
  122. st_synchronize();
  123. max_feedrate[E_AXIS] = 50;
  124. lcd_update_enable(true);
  125. lcd_return_to_status();
  126. lcdDrawUpdate = 2;
  127. #endif
  128. }
  129. void extr_unload()
  130. { //unload just current filament for multimaterial printers
  131. #ifdef SNMM
  132. float tmp_motor[3] = DEFAULT_PWM_MOTOR_CURRENT;
  133. float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD;
  134. uint8_t SilentMode = eeprom_read_byte((uint8_t*)EEPROM_SILENT);
  135. #endif
  136. if (degHotend0() > EXTRUDE_MINTEMP)
  137. {
  138. #ifndef SNMM
  139. st_synchronize();
  140. //show which filament is currently unloaded
  141. lcd_update_enable(false);
  142. lcd_clear();
  143. lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
  144. lcd_print(" ");
  145. lcd_print(snmm_extruder + 1);
  146. current_position[E_AXIS] -= 80;
  147. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
  148. st_synchronize();
  149. printf_P(PSTR("U0\n"));
  150. fprintf_P(uart2io, PSTR("U0\n"));
  151. // get response
  152. manage_response();
  153. lcd_update_enable(true);
  154. #else //SNMM
  155. lcd_clear();
  156. lcd_display_message_fullscreen_P(PSTR(""));
  157. max_feedrate[E_AXIS] = 50;
  158. lcd_set_cursor(0, 0); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
  159. lcd_print(" ");
  160. lcd_print(snmm_extruder + 1);
  161. lcd_set_cursor(0, 2); lcd_puts_P(_T(MSG_PLEASE_WAIT));
  162. if (current_position[Z_AXIS] < 15) {
  163. current_position[Z_AXIS] += 15; //lifting in Z direction to make space for extrusion
  164. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 25, active_extruder);
  165. }
  166. current_position[E_AXIS] += 10; //extrusion
  167. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 10, active_extruder);
  168. st_current_set(2, E_MOTOR_HIGH_CURRENT);
  169. if (current_temperature[0] < 230) { //PLA & all other filaments
  170. current_position[E_AXIS] += 5.4;
  171. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2800 / 60, active_extruder);
  172. current_position[E_AXIS] += 3.2;
  173. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
  174. current_position[E_AXIS] += 3;
  175. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3400 / 60, active_extruder);
  176. }
  177. else { //ABS
  178. current_position[E_AXIS] += 3.1;
  179. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2000 / 60, active_extruder);
  180. current_position[E_AXIS] += 3.1;
  181. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
  182. current_position[E_AXIS] += 4;
  183. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
  184. /*current_position[X_AXIS] += 23; //delay
  185. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay
  186. current_position[X_AXIS] -= 23; //delay
  187. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600 / 60, active_extruder); //delay*/
  188. delay_keep_alive(4700);
  189. }
  190. max_feedrate[E_AXIS] = 80;
  191. current_position[E_AXIS] -= (bowden_length[snmm_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
  192. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
  193. current_position[E_AXIS] -= (bowden_length[snmm_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
  194. plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
  195. st_synchronize();
  196. //st_current_init();
  197. if (SilentMode != SILENT_MODE_OFF) st_current_set(2, tmp_motor[2]); //set back to normal operation currents
  198. else st_current_set(2, tmp_motor_loud[2]);
  199. lcd_update_enable(true);
  200. lcd_return_to_status();
  201. max_feedrate[E_AXIS] = 50;
  202. #endif //SNMM
  203. }
  204. else
  205. {
  206. lcd_clear();
  207. lcd_set_cursor(0, 0);
  208. lcd_puts_P(_T(MSG_ERROR));
  209. lcd_set_cursor(0, 2);
  210. lcd_puts_P(_T(MSG_PREHEAT_NOZZLE));
  211. delay(2000);
  212. lcd_clear();
  213. }
  214. //lcd_return_to_status();
  215. }
  216. //wrapper functions for loading filament
  217. void extr_adj_0()
  218. {
  219. #ifndef SNMM
  220. enquecommand_P(PSTR("M701 E0"));
  221. #else
  222. change_extr(0);
  223. extr_adj(0);
  224. #endif
  225. }
  226. void extr_adj_1()
  227. {
  228. #ifndef SNMM
  229. enquecommand_P(PSTR("M701 E1"));
  230. #else
  231. change_extr(1);
  232. extr_adj(1);
  233. #endif
  234. }
  235. void extr_adj_2()
  236. {
  237. #ifndef SNMM
  238. enquecommand_P(PSTR("M701 E2"));
  239. #else
  240. change_extr(2);
  241. extr_adj(2);
  242. #endif
  243. }
  244. void extr_adj_3()
  245. {
  246. #ifndef SNMM
  247. enquecommand_P(PSTR("M701 E3"));
  248. #else
  249. change_extr(3);
  250. extr_adj(3);
  251. #endif
  252. }
  253. void extr_adj_4()
  254. {
  255. #ifndef SNMM
  256. enquecommand_P(PSTR("M701 E4"));
  257. #else
  258. change_extr(4);
  259. extr_adj(4);
  260. #endif
  261. }
  262. void load_all()
  263. {
  264. #ifndef SNMM
  265. enquecommand_P(PSTR("M701 E0"));
  266. enquecommand_P(PSTR("M701 E1"));
  267. enquecommand_P(PSTR("M701 E2"));
  268. enquecommand_P(PSTR("M701 E3"));
  269. enquecommand_P(PSTR("M701 E4"));
  270. #else
  271. for (int i = 0; i < 4; i++)
  272. {
  273. change_extr(i);
  274. extr_adj(i);
  275. }
  276. #endif
  277. }
  278. //wrapper functions for changing extruders
  279. void extr_change_0()
  280. {
  281. change_extr(0);
  282. lcd_return_to_status();
  283. }
  284. void extr_change_1()
  285. {
  286. change_extr(1);
  287. lcd_return_to_status();
  288. }
  289. void extr_change_2()
  290. {
  291. change_extr(2);
  292. lcd_return_to_status();
  293. }
  294. void extr_change_3()
  295. {
  296. change_extr(3);
  297. lcd_return_to_status();
  298. }
  299. //wrapper functions for unloading filament
  300. void extr_unload_all()
  301. {
  302. if (degHotend0() > EXTRUDE_MINTEMP)
  303. {
  304. for (int i = 0; i < 4; i++)
  305. {
  306. change_extr(i);
  307. extr_unload();
  308. }
  309. }
  310. else
  311. {
  312. lcd_clear();
  313. lcd_set_cursor(0, 0);
  314. lcd_puts_P(_T(MSG_ERROR));
  315. lcd_set_cursor(0, 2);
  316. lcd_puts_P(_T(MSG_PREHEAT_NOZZLE));
  317. delay(2000);
  318. lcd_clear();
  319. lcd_return_to_status();
  320. }
  321. }
  322. //unloading just used filament (for snmm)
  323. void extr_unload_used()
  324. {
  325. if (degHotend0() > EXTRUDE_MINTEMP) {
  326. for (int i = 0; i < 4; i++) {
  327. if (snmm_filaments_used & (1 << i)) {
  328. change_extr(i);
  329. extr_unload();
  330. }
  331. }
  332. snmm_filaments_used = 0;
  333. }
  334. else {
  335. lcd_clear();
  336. lcd_set_cursor(0, 0);
  337. lcd_puts_P(_T(MSG_ERROR));
  338. lcd_set_cursor(0, 2);
  339. lcd_puts_P(_T(MSG_PREHEAT_NOZZLE));
  340. delay(2000);
  341. lcd_clear();
  342. lcd_return_to_status();
  343. }
  344. }
  345. void extr_unload_0()
  346. {
  347. change_extr(0);
  348. extr_unload();
  349. }
  350. void extr_unload_1()
  351. {
  352. change_extr(1);
  353. extr_unload();
  354. }
  355. void extr_unload_2()
  356. {
  357. change_extr(2);
  358. extr_unload();
  359. }
  360. void extr_unload_3()
  361. {
  362. change_extr(3);
  363. extr_unload();
  364. }
  365. void extr_unload_4()
  366. {
  367. change_extr(4);
  368. extr_unload();
  369. }