mmu.cpp 10 KB

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