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.

anycubic_i3mega_lcd.cpp 37KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. /**
  2. * anycubic_i3mega_lcd.cpp --- Support for Anycubic i3 Mega TFT
  3. * Created by Christian Hopp on 09.12.17.
  4. * Improved by David Ramiro
  5. * Converted to ext_iu by John BouAntoun 21 June 2020
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "../../../../inc/MarlinConfigPre.h"
  22. #if ENABLED(ANYCUBIC_LCD_I3MEGA)
  23. #include "anycubic_i3mega_lcd.h"
  24. #include "../../../../inc/MarlinConfig.h"
  25. #include "../../ui_api.h"
  26. #include "../../../../MarlinCore.h" // for quickstop_stepper and disable_steppers
  27. #include "../../../../module/motion.h" // for A20 read printing speed feedrate_percentage
  28. // command sending macro's with debugging capability
  29. #define SEND_PGM(x) send_P(PSTR(x))
  30. #define SENDLINE_PGM(x) sendLine_P(PSTR(x))
  31. #define SEND_PGM_VAL(x,y) (send_P(PSTR(x)), sendLine(itostr3(y)))
  32. #define SEND(x) send(x)
  33. #define SENDLINE(x) sendLine(x)
  34. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  35. #define SENDLINE_DBG_PGM(x,y) (sendLine_P(PSTR(x)), SERIAL_ECHOLNPGM(y))
  36. #define SENDLINE_DBG_PGM_VAL(x,y,z) (sendLine_P(PSTR(x)), SERIAL_ECHOPGM(y), SERIAL_ECHOLN(z))
  37. #else
  38. #define SENDLINE_DBG_PGM(x,y) sendLine_P(PSTR(x))
  39. #define SENDLINE_DBG_PGM_VAL(x,y,z) sendLine_P(PSTR(x))
  40. #endif
  41. AnycubicTFTClass AnycubicTFT;
  42. char _conv[8];
  43. char *itostr2(const uint8_t &x) {
  44. // sprintf(conv,"%5.1f",x);
  45. int xx = x;
  46. _conv[0] = (xx / 10) % 10 + '0';
  47. _conv[1] = (xx) % 10 + '0';
  48. _conv[2] = 0;
  49. return _conv;
  50. }
  51. static void sendNewLine(void) {
  52. LCD_SERIAL.write('\r');
  53. LCD_SERIAL.write('\n');
  54. }
  55. static void send(const char *str) {
  56. LCD_SERIAL.print(str);
  57. }
  58. static void sendLine(const char *str) {
  59. send(str);
  60. sendNewLine();
  61. }
  62. static void send_P(PGM_P str) {
  63. while (const char c = pgm_read_byte(str++))
  64. LCD_SERIAL.write(c);
  65. }
  66. static void sendLine_P(PGM_P str) {
  67. send_P(str);
  68. sendNewLine();
  69. }
  70. #ifndef ULTRA_LCD
  71. #define DIGIT(n) ('0' + (n))
  72. #define DIGIMOD(n, f) DIGIT((n) / (f) % 10)
  73. #define RJDIGIT(n, f) ((n) >= (f) ? DIGIMOD(n, f) : ' ')
  74. #define MINUSOR(n, alt) (n >= 0 ? (alt) : (n = -n, '-'))
  75. char* itostr3(const int x) {
  76. int xx = x;
  77. _conv[4] = MINUSOR(xx, RJDIGIT(xx, 100));
  78. _conv[5] = RJDIGIT(xx, 10);
  79. _conv[6] = DIGIMOD(xx, 1);
  80. return &_conv[4];
  81. }
  82. // Convert signed float to fixed-length string with 023.45 / -23.45 format
  83. char *ftostr32(const float &x) {
  84. long xx = x * 100;
  85. _conv[1] = MINUSOR(xx, DIGIMOD(xx, 10000));
  86. _conv[2] = DIGIMOD(xx, 1000);
  87. _conv[3] = DIGIMOD(xx, 100);
  88. _conv[4] = '.';
  89. _conv[5] = DIGIMOD(xx, 10);
  90. _conv[6] = DIGIMOD(xx, 1);
  91. return &_conv[1];
  92. }
  93. #endif
  94. AnycubicTFTClass::AnycubicTFTClass() {}
  95. void AnycubicTFTClass::OnSetup() {
  96. #ifndef LCD_BAUDRATE
  97. #define LCD_BAUDRATE 115200
  98. #endif
  99. LCD_SERIAL.begin(LCD_BAUDRATE);
  100. SENDLINE_DBG_PGM("J17", "TFT Serial Debug: Main board reset... J17"); // J17 Main board reset
  101. ExtUI::delay_ms(10);
  102. // initialise the state of the key pins running on the tft
  103. #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
  104. SET_INPUT_PULLUP(SD_DETECT_PIN);
  105. #endif
  106. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  107. SET_INPUT_PULLUP(FIL_RUNOUT_PIN);
  108. #endif
  109. mediaPrintingState = AMPRINTSTATE_NOT_PRINTING;
  110. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  111. // DoSDCardStateCheck();
  112. SENDLINE_DBG_PGM("J12", "TFT Serial Debug: Ready... J12"); // J12 Ready
  113. ExtUI::delay_ms(10);
  114. DoFilamentRunoutCheck();
  115. SelectedFile[0] = 0;
  116. #if ENABLED(STARTUP_CHIME)
  117. ExtUI::injectCommands_P(PSTR("M300 P250 S554\nM300 P250 S554\nM300 P250 S740\nM300 P250 S554\nM300 P250 S740\nM300 P250 S554\nM300 P500 S831"));
  118. #endif
  119. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  120. SERIAL_ECHOLNPGM("TFT Serial Debug: Finished startup");
  121. #endif
  122. }
  123. void AnycubicTFTClass::OnCommandScan() {
  124. static millis_t nextStopCheck = 0; // used to slow the stopped print check down to reasonable times
  125. const millis_t ms = millis();
  126. if (ELAPSED(ms, nextStopCheck)) {
  127. nextStopCheck = ms + 1000UL;
  128. if (mediaPrintingState == AMPRINTSTATE_STOP_REQUESTED && IsNozzleHomed()) {
  129. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  130. SERIAL_ECHOLNPGM("TFT Serial Debug: Finished stopping print, releasing motors ...");
  131. #endif
  132. mediaPrintingState = AMPRINTSTATE_NOT_PRINTING;
  133. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  134. ExtUI::injectCommands_P(PSTR("M84\nM27")); // disable stepper motors and force report of SD status
  135. ExtUI::delay_ms(200);
  136. // tell printer to release resources of print to indicate it is done
  137. SENDLINE_DBG_PGM("J14", "TFT Serial Debug: SD Print Stopped... J14");
  138. }
  139. }
  140. if (TFTbuflen < (TFTBUFSIZE - 1))
  141. GetCommandFromTFT();
  142. if (TFTbuflen) {
  143. TFTbuflen = (TFTbuflen - 1);
  144. TFTbufindr = (TFTbufindr + 1) % TFTBUFSIZE;
  145. }
  146. }
  147. void AnycubicTFTClass::OnKillTFT() {
  148. SENDLINE_DBG_PGM("J11", "TFT Serial Debug: Kill command... J11");
  149. }
  150. void AnycubicTFTClass::OnSDCardStateChange(bool isInserted) {
  151. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  152. SERIAL_ECHOPGM("TFT Serial Debug: OnSDCardStateChange event triggered...");
  153. SERIAL_ECHO(itostr2(isInserted));
  154. SERIAL_EOL();
  155. #endif
  156. DoSDCardStateCheck();
  157. }
  158. void AnycubicTFTClass::OnSDCardError() {
  159. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  160. SERIAL_ECHOLNPGM("TFT Serial Debug: OnSDCardError event triggered...");
  161. #endif
  162. SENDLINE_DBG_PGM("J21", "TFT Serial Debug: On SD Card Error ... J21");
  163. }
  164. void AnycubicTFTClass::OnFilamentRunout() {
  165. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  166. SERIAL_ECHOLNPGM("TFT Serial Debug: FilamentRunout triggered...");
  167. #endif
  168. DoFilamentRunoutCheck();
  169. }
  170. void AnycubicTFTClass::OnUserConfirmRequired(const char * const msg) {
  171. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  172. SERIAL_ECHOPGM("TFT Serial Debug: OnUserConfirmRequired triggered... ");
  173. SERIAL_ECHOLN(msg);
  174. #endif
  175. #if ENABLED(SDSUPPORT)
  176. /**
  177. * Need to handle the process of following states
  178. * "Nozzle Parked"
  179. * "Load Filament"
  180. * "Filament Purging..."
  181. * "HeaterTimeout"
  182. * "Reheat finished."
  183. *
  184. * NOTE: The only way to handle these states is strcmp_P with the msg unfortunately (very expensive)
  185. */
  186. if (strcmp_P(msg, PSTR("Nozzle Parked")) == 0) {
  187. mediaPrintingState = AMPRINTSTATE_PAUSED;
  188. mediaPauseState = AMPAUSESTATE_PARKED;
  189. // enable continue button
  190. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD print paused done... J18");
  191. }
  192. else if (strcmp_P(msg, PSTR("Load Filament")) == 0) {
  193. mediaPrintingState = AMPRINTSTATE_PAUSED;
  194. mediaPauseState = AMPAUSESTATE_FILAMENT_OUT;
  195. // enable continue button
  196. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm Filament is out... J18");
  197. SENDLINE_DBG_PGM("J23", "TFT Serial Debug: UserConfirm Blocking filament prompt... J23");
  198. }
  199. else if (strcmp_P(msg, PSTR("Filament Purging...")) == 0) {
  200. mediaPrintingState = AMPRINTSTATE_PAUSED;
  201. mediaPauseState = AMPAUSESTATE_PARKING;
  202. // TODO: JBA I don't think J05 just disables the continue button, i think it injects a rogue M25. So taking this out
  203. // disable continue button
  204. // SENDLINE_DBG_PGM("J05", "TFT Serial Debug: UserConfirm SD Filament Purging... J05"); // J05 printing pause
  205. // enable continue button
  206. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm Filament is purging... J18");
  207. }
  208. else if (strcmp_P(msg, PSTR("HeaterTimeout")) == 0) {
  209. mediaPrintingState = AMPRINTSTATE_PAUSED;
  210. mediaPauseState = AMPAUSESTATE_HEATER_TIMEOUT;
  211. // enable continue button
  212. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD Heater timeout... J18");
  213. }
  214. else if (strcmp_P(msg, PSTR("Reheat finished.")) == 0) {
  215. mediaPrintingState = AMPRINTSTATE_PAUSED;
  216. mediaPauseState = AMPAUSESTATE_REHEAT_FINISHED;
  217. // enable continue button
  218. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: UserConfirm SD Reheat done... J18");
  219. }
  220. #endif
  221. }
  222. float AnycubicTFTClass::CodeValue() {
  223. return (strtod(&TFTcmdbuffer[TFTbufindr][TFTstrchr_pointer - TFTcmdbuffer[TFTbufindr] + 1], NULL));
  224. }
  225. bool AnycubicTFTClass::CodeSeen(char code) {
  226. TFTstrchr_pointer = strchr(TFTcmdbuffer[TFTbufindr], code);
  227. return (TFTstrchr_pointer != NULL); // Return True if a character was found
  228. }
  229. bool AnycubicTFTClass::IsNozzleHomed() {
  230. const float xPosition = ExtUI::getAxisPosition_mm((ExtUI::axis_t) ExtUI::X);
  231. const float yPosition = ExtUI::getAxisPosition_mm((ExtUI::axis_t) ExtUI::Y);
  232. return WITHIN(xPosition, X_MIN_POS - 0.1, X_MIN_POS + 0.1) &&
  233. WITHIN(yPosition, Y_MIN_POS - 0.1, Y_MIN_POS + 0.1);
  234. }
  235. void AnycubicTFTClass::HandleSpecialMenu() {
  236. /**
  237. * NOTE: that the file selection command actual lowercases the entire selected file/foldername, so charracter comparisons need to be lowercase.
  238. */
  239. if (SelectedDirectory[0] == '<') {
  240. switch (SelectedDirectory[1]) {
  241. case 'e': // "<exit>"
  242. SpecialMenu = false;
  243. return;
  244. break;
  245. #if ENABLED(PROBE_MANUALLY)
  246. case '0':
  247. switch (SelectedDirectory[2]) {
  248. case '1': // "<01ZUp0.1>"
  249. SERIAL_ECHOLNPGM("Special Menu: Z Up 0.1");
  250. ExtUI::injectCommands_P(PSTR("G91\nG1 Z+0.1\nG90"));
  251. break;
  252. case '2': // "<02ZUp0.02>"
  253. SERIAL_ECHOLNPGM("Special Menu: Z Up 0.02");
  254. ExtUI::injectCommands_P(PSTR("G91\nG1 Z+0.02\nG90"));
  255. break;
  256. case '3': // "<03ZDn0.02>"
  257. SERIAL_ECHOLNPGM("Special Menu: Z Down 0.02");
  258. ExtUI::injectCommands_P(PSTR("G91\nG1 Z-0.02\nG90"));
  259. break;
  260. case '4': // "<04ZDn0.1>"
  261. SERIAL_ECHOLNPGM("Special Menu: Z Down 0.1");
  262. ExtUI::injectCommands_P(PSTR("G91\nG1 Z-0.1\nG90"));
  263. break;
  264. case '5': // "<05PrehtBed>"
  265. SERIAL_ECHOLNPGM("Special Menu: Preheat Bed");
  266. ExtUI::injectCommands_P(PSTR("M140 S65"));
  267. break;
  268. case '6': // "<06SMeshLvl>"
  269. SERIAL_ECHOLNPGM("Special Menu: Start Mesh Leveling");
  270. ExtUI::injectCommands_P(PSTR("G29 S1"));
  271. break;
  272. case '7': // "<07MeshNPnt>"
  273. SERIAL_ECHOLNPGM("Special Menu: Next Mesh Point");
  274. ExtUI::injectCommands_P(PSTR("G29 S2"));
  275. break;
  276. case '8': // "<08HtEndPID>"
  277. SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotend PID");
  278. // need to dwell for half a second to give the fan a chance to start before the pid tuning starts
  279. ExtUI::injectCommands_P(PSTR("M106 S204\nG4 P500\nM303 E0 S215 C15 U1"));
  280. break;
  281. case '9': // "<09HtBedPID>"
  282. SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotbed Pid");
  283. ExtUI::injectCommands_P(PSTR("M303 E-1 S65 C6 U1"));
  284. break;
  285. default:
  286. break;
  287. }
  288. break;
  289. case '1':
  290. switch (SelectedDirectory[2]) {
  291. case '0': // "<10FWDeflts>"
  292. SERIAL_ECHOLNPGM("Special Menu: Load FW Defaults");
  293. ExtUI::injectCommands_P(PSTR("M502\nM300 P105 S1661\nM300 P210 S1108"));
  294. break;
  295. case '1': // "<11SvEEPROM>"
  296. SERIAL_ECHOLNPGM("Special Menu: Save EEPROM");
  297. ExtUI::injectCommands_P(PSTR("M500\nM300 P105 S1108\nM300 P210 S1661"));
  298. break;
  299. default:
  300. break;
  301. }
  302. break;
  303. #else // if ENABLED(PROBE_MANUALLY)
  304. case '0':
  305. switch (SelectedDirectory[2]) {
  306. case '1': // "<01PrehtBed>"
  307. SERIAL_ECHOLNPGM("Special Menu: Preheat Bed");
  308. ExtUI::injectCommands_P(PSTR("M140 S65"));
  309. break;
  310. case '2': // "<02ABL>"
  311. SERIAL_ECHOLNPGM("Special Menu: Auto Bed Leveling");
  312. ExtUI::injectCommands_P(PSTR("G28\nG29"));
  313. break;
  314. case '3': // "<03HtendPID>"
  315. SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotend PID");
  316. // need to dwell for half a second to give the fan a chance to start before the pid tuning starts
  317. ExtUI::injectCommands_P(PSTR("M106 S204\nG4 P500\nM303 E0 S215 C15 U1"));
  318. break;
  319. case '4': // "<04HtbedPID>"
  320. SERIAL_ECHOLNPGM("Special Menu: Auto Tune Hotbed Pid");
  321. ExtUI::injectCommands_P(PSTR("M303 E-1 S65 C6 U1"));
  322. break;
  323. case '5': // "<05FWDeflts>"
  324. SERIAL_ECHOLNPGM("Special Menu: Load FW Defaults");
  325. ExtUI::injectCommands_P(PSTR("M502\nM300 P105 S1661\nM300 P210 S1108"));
  326. break;
  327. case '6': // "<06SvEEPROM>"
  328. SERIAL_ECHOLNPGM("Special Menu: Save EEPROM");
  329. ExtUI::injectCommands_P(PSTR("M500\nM300 P105 S1108\nM300 P210 S1661"));
  330. break;
  331. case '7': // <07SendM108>
  332. SERIAL_ECHOLNPGM("Special Menu: Send User Confirmation");
  333. ExtUI::injectCommands_P(PSTR("M108"));
  334. break;
  335. default:
  336. break;
  337. }
  338. break;
  339. #endif // PROBE_MANUALLY
  340. default:
  341. break;
  342. }
  343. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  344. }
  345. else {
  346. SERIAL_ECHOPGM("TFT Serial Debug: Attempted to HandleSpecialMenu on non-special menu... ");
  347. SERIAL_ECHOLN(SelectedDirectory);
  348. #endif
  349. }
  350. }
  351. void AnycubicTFTClass::RenderCurrentFileList() {
  352. #if ENABLED(SDSUPPORT)
  353. uint16_t selectedNumber = 0;
  354. SelectedDirectory[0] = 0;
  355. SelectedFile[0] = 0;
  356. ExtUI::FileList currentFileList;
  357. SENDLINE_PGM("FN "); // Filelist start
  358. if (!ExtUI::isMediaInserted() && !SpecialMenu) {
  359. SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to render Current File List... J02");
  360. SENDLINE_PGM("<Special_Menu>");
  361. SENDLINE_PGM("<Special_Menu>");
  362. }
  363. else {
  364. if (CodeSeen('S'))
  365. selectedNumber = CodeValue();
  366. if (SpecialMenu)
  367. RenderSpecialMenu(selectedNumber);
  368. else if (selectedNumber <= currentFileList.count())
  369. RenderCurrentFolder(selectedNumber);
  370. }
  371. SENDLINE_PGM("END"); // Filelist stop
  372. #endif // SDSUPPORT
  373. }
  374. void AnycubicTFTClass::RenderSpecialMenu(uint16_t selectedNumber) {
  375. switch (selectedNumber) {
  376. #if ENABLED(PROBE_MANUALLY)
  377. case 0: // First Page
  378. SENDLINE_PGM("<01ZUp0.1>");
  379. SENDLINE_PGM("<Z Up 0.1>");
  380. SENDLINE_PGM("<02ZUp0.02>");
  381. SENDLINE_PGM("<Z Up 0.02>");
  382. SENDLINE_PGM("<03ZDn0.02>");
  383. SENDLINE_PGM("<Z Down 0.02>");
  384. SENDLINE_PGM("<04ZDn0.1>");
  385. SENDLINE_PGM("<Z Down 0.1>");
  386. break;
  387. case 4: // Second Page
  388. SENDLINE_PGM("<05PrehtBed>");
  389. SENDLINE_PGM("<Preheat bed>");
  390. SENDLINE_PGM("<06SMeshLvl>");
  391. SENDLINE_PGM("<Start Mesh Leveling>");
  392. SENDLINE_PGM("<07MeshNPnt>");
  393. SENDLINE_PGM("<Next Mesh Point>");
  394. SENDLINE_PGM("<08HtEndPID>");
  395. SENDLINE_PGM("<Auto Tune Hotend PID>");
  396. break;
  397. case 8: // Third Page
  398. SENDLINE_PGM("<09HtBedPID>");
  399. SENDLINE_PGM("<Auto Tune Hotbed PID>");
  400. SENDLINE_PGM("<10FWDeflts>");
  401. SENDLINE_PGM("<Load FW Defaults>");
  402. SENDLINE_PGM("<11SvEEPROM>");
  403. SENDLINE_PGM("<Save EEPROM>");
  404. SENDLINE_PGM("<Exit>");
  405. SENDLINE_PGM("<Exit>");
  406. break;
  407. #else
  408. case 0: // First Page
  409. SENDLINE_PGM("<01PrehtBed>");
  410. SENDLINE_PGM("<Preheat bed>");
  411. SENDLINE_PGM("<02ABL>");
  412. SENDLINE_PGM("<Auto Bed Leveling>");
  413. SENDLINE_PGM("<03HtEndPID>");
  414. SENDLINE_PGM("<Auto Tune Hotend PID>");
  415. SENDLINE_PGM("<04HtBedPID>");
  416. SENDLINE_PGM("<Auto Tune Hotbed PID>");
  417. break;
  418. case 4: // Second Page
  419. SENDLINE_PGM("<05FWDeflts>");
  420. SENDLINE_PGM("<Load FW Defaults>");
  421. SENDLINE_PGM("<06SvEEPROM>");
  422. SENDLINE_PGM("<Save EEPROM>");
  423. SENDLINE_PGM("<07SendM108>");
  424. SENDLINE_PGM("<Send User Confirmation>");
  425. SENDLINE_PGM("<Exit>");
  426. SENDLINE_PGM("<Exit>");
  427. break;
  428. #endif // PROBE_MANUALLY
  429. default:
  430. break;
  431. }
  432. }
  433. void AnycubicTFTClass::RenderCurrentFolder(uint16_t selectedNumber) {
  434. ExtUI::FileList currentFileList;
  435. uint16_t cnt = selectedNumber;
  436. uint16_t max_files;
  437. uint16_t dir_files = currentFileList.count();
  438. if ((dir_files - selectedNumber) < 4)
  439. max_files = dir_files;
  440. else
  441. max_files = selectedNumber + 3;
  442. for (cnt = selectedNumber; cnt <= max_files; cnt++) {
  443. if (cnt == 0) { // Special Entry
  444. if (currentFileList.isAtRootDir()) {
  445. SENDLINE_PGM("<specialmnu>");
  446. SENDLINE_PGM("<Special Menu>");
  447. }
  448. else {
  449. SENDLINE_PGM("/..");
  450. SENDLINE_PGM("/..");
  451. }
  452. }
  453. else {
  454. currentFileList.seek(cnt - 1, false);
  455. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  456. SERIAL_ECHOLN(currentFileList.filename());
  457. #endif
  458. if (currentFileList.isDir()) {
  459. SEND_PGM("/");
  460. SENDLINE(currentFileList.shortFilename());
  461. SEND_PGM("/");
  462. SENDLINE(currentFileList.longFilename());
  463. }
  464. else {
  465. SENDLINE(currentFileList.shortFilename());
  466. SENDLINE(currentFileList.longFilename());
  467. }
  468. }
  469. }
  470. }
  471. void AnycubicTFTClass::OnPrintTimerStarted() {
  472. #if ENABLED(SDSUPPORT)
  473. if (mediaPrintingState == AMPRINTSTATE_PRINTING)
  474. SENDLINE_DBG_PGM("J04", "TFT Serial Debug: Starting SD Print... J04"); // J04 Starting Print
  475. #endif
  476. }
  477. void AnycubicTFTClass::OnPrintTimerPaused() {
  478. #if ENABLED(SDSUPPORT)
  479. if (ExtUI::isPrintingFromMedia()) {
  480. mediaPrintingState = AMPRINTSTATE_PAUSED;
  481. mediaPauseState = AMPAUSESTATE_PARKING;
  482. }
  483. #endif
  484. }
  485. void AnycubicTFTClass::OnPrintTimerStopped() {
  486. #if ENABLED(SDSUPPORT)
  487. if (mediaPrintingState == AMPRINTSTATE_PRINTING) {
  488. mediaPrintingState = AMPRINTSTATE_NOT_PRINTING;
  489. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  490. SENDLINE_DBG_PGM("J14", "TFT Serial Debug: SD Print Completed... J14");
  491. }
  492. // otherwise it was stopped by the printer so don't send print completed signal to TFT
  493. #endif
  494. }
  495. void AnycubicTFTClass::GetCommandFromTFT() {
  496. char *starpos = NULL;
  497. while (LCD_SERIAL.available() > 0 && TFTbuflen < TFTBUFSIZE) {
  498. serial3_char = LCD_SERIAL.read();
  499. if (serial3_char == '\n' ||
  500. serial3_char == '\r' ||
  501. serial3_char == ':' ||
  502. serial3_count >= (TFT_MAX_CMD_SIZE - 1)
  503. ) {
  504. if (!serial3_count) return; // if empty line
  505. TFTcmdbuffer[TFTbufindw][serial3_count] = 0; // terminate string
  506. if ((strchr(TFTcmdbuffer[TFTbufindw], 'A') != NULL)) {
  507. int16_t a_command;
  508. TFTstrchr_pointer = strchr(TFTcmdbuffer[TFTbufindw], 'A');
  509. a_command = ((int)((strtod(&TFTcmdbuffer[TFTbufindw][TFTstrchr_pointer - TFTcmdbuffer[TFTbufindw] + 1], NULL))));
  510. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  511. if ((a_command > 7) && (a_command != 20)) { // No debugging of status polls, please!
  512. SERIAL_ECHOPGM("TFT Serial Command: ");
  513. SERIAL_ECHOLN(TFTcmdbuffer[TFTbufindw]);
  514. }
  515. #endif
  516. switch (a_command) {
  517. case 0: { // A0 GET HOTEND TEMP
  518. float hotendActualTemp = ExtUI::getActualTemp_celsius((ExtUI::extruder_t) (ExtUI::extruder_t) ExtUI::E0);
  519. SEND_PGM_VAL("A0V ", int(hotendActualTemp + 0.5));
  520. }
  521. break;
  522. case 1: { // A1 GET HOTEND TARGET TEMP
  523. float hotendTargetTemp = ExtUI::getTargetTemp_celsius((ExtUI::extruder_t) (ExtUI::extruder_t) ExtUI::E0);
  524. SEND_PGM_VAL("A1V ", int(hotendTargetTemp + 0.5));
  525. }
  526. break;
  527. case 2: { // A2 GET HOTBED TEMP
  528. float heatedBedActualTemp = ExtUI::getActualTemp_celsius((ExtUI::heater_t) ExtUI::BED);
  529. SEND_PGM_VAL("A2V ", int(heatedBedActualTemp + 0.5));
  530. }
  531. break;
  532. case 3: { // A3 GET HOTBED TARGET TEMP
  533. float heatedBedTargetTemp = ExtUI::getTargetTemp_celsius((ExtUI::heater_t) ExtUI::BED);
  534. SEND_PGM_VAL("A3V ", int(heatedBedTargetTemp + 0.5));
  535. }
  536. break;
  537. case 4: // A4 GET FAN SPEED
  538. {
  539. float fanPercent = ExtUI::getActualFan_percent(ExtUI::FAN0);
  540. fanPercent = constrain(fanPercent, 0, 100);
  541. SEND_PGM_VAL("A4V ", int(fanPercent));
  542. }
  543. break;
  544. case 5: // A5 GET CURRENT COORDINATE
  545. {
  546. float xPostition = ExtUI::getAxisPosition_mm(ExtUI::X);
  547. float yPostition = ExtUI::getAxisPosition_mm(ExtUI::Y);
  548. float zPostition = ExtUI::getAxisPosition_mm(ExtUI::Z);
  549. SEND_PGM("A5V X: ");
  550. LCD_SERIAL.print(xPostition);
  551. SEND_PGM(" Y: ");
  552. LCD_SERIAL.print(yPostition);
  553. SEND_PGM(" Z: ");
  554. LCD_SERIAL.print(zPostition);
  555. SENDLINE_PGM("");
  556. }
  557. break;
  558. case 6: // A6 GET SD CARD PRINTING STATUS
  559. #if ENABLED(SDSUPPORT)
  560. if (ExtUI::isPrintingFromMedia()) {
  561. SEND_PGM("A6V ");
  562. if (ExtUI::isMediaInserted()) {
  563. SENDLINE(itostr3(int(ExtUI::getProgress_percent())));
  564. }
  565. else {
  566. SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to return printing status... J02");
  567. }
  568. }
  569. else {
  570. SENDLINE_PGM("A6V ---");
  571. }
  572. #endif
  573. break;
  574. case 7: { // A7 GET PRINTING TIME
  575. uint32_t elapsedSeconds = ExtUI::getProgress_seconds_elapsed();
  576. SEND_PGM("A7V ");
  577. if (elapsedSeconds != 0) { // print time
  578. uint32_t elapsedMinutes = elapsedSeconds / 60;
  579. SEND(itostr2(elapsedMinutes / 60));
  580. SEND_PGM(" H ");
  581. SEND(itostr2(elapsedMinutes % 60));
  582. SENDLINE_PGM(" M");
  583. }
  584. else {
  585. SENDLINE_PGM(" 999:999");
  586. }
  587. }
  588. break;
  589. case 8: // A8 GET SD LIST
  590. #if ENABLED(SDSUPPORT)
  591. SelectedFile[0] = 0;
  592. RenderCurrentFileList();
  593. #endif
  594. break;
  595. case 9: // A9 pause sd print
  596. #if ENABLED(SDSUPPORT)
  597. if (ExtUI::isPrintingFromMedia())
  598. PausePrint();
  599. #endif
  600. break;
  601. case 10: // A10 resume sd print
  602. #if ENABLED(SDSUPPORT)
  603. if (ExtUI::isPrintingFromMediaPaused())
  604. ResumePrint();
  605. #endif
  606. break;
  607. case 11: // A11 STOP SD PRINT
  608. #if ENABLED(SDSUPPORT)
  609. StopPrint();
  610. #endif
  611. break;
  612. case 12: // A12 kill
  613. kill(PSTR(STR_ERR_KILLED));
  614. break;
  615. case 13: // A13 SELECTION FILE
  616. #if ENABLED(SDSUPPORT)
  617. if (ExtUI::isMediaInserted()) {
  618. starpos = (strchr(TFTstrchr_pointer + 4, '*'));
  619. if (TFTstrchr_pointer[4] == '/') {
  620. strcpy(SelectedDirectory, TFTstrchr_pointer + 5);
  621. SelectedFile[0] = 0;
  622. SENDLINE_DBG_PGM("J21", "TFT Serial Debug: Clear file selection... J21 "); // J21 Not File Selected
  623. SENDLINE_PGM("");
  624. }
  625. else if (TFTstrchr_pointer[4] == '<') {
  626. strcpy(SelectedDirectory, TFTstrchr_pointer + 4);
  627. SpecialMenu = true;
  628. SelectedFile[0] = 0;
  629. SENDLINE_DBG_PGM("J21", "TFT Serial Debug: Clear file selection... J21 "); // J21 Not File Selected
  630. SENDLINE_PGM("");
  631. }
  632. else {
  633. SelectedDirectory[0] = 0;
  634. if (starpos != NULL)
  635. *(starpos - 1) = '\0';
  636. strcpy(SelectedFile, TFTstrchr_pointer + 4);
  637. SENDLINE_DBG_PGM_VAL("J20", "TFT Serial Debug: File Selected... J20 ", SelectedFile); // J20 File Selected
  638. }
  639. }
  640. #endif
  641. break;
  642. case 14: // A14 START PRINTING
  643. #if ENABLED(SDSUPPORT)
  644. if (!ExtUI::isPrinting() && strlen(SelectedFile) > 0)
  645. StartPrint();
  646. #endif
  647. break;
  648. case 15: // A15 RESUMING FROM OUTAGE
  649. // TODO: JBA implement resume form outage
  650. break;
  651. case 16: { // A16 set hotend temp
  652. unsigned int tempvalue;
  653. if (CodeSeen('S')) {
  654. tempvalue = constrain(CodeValue(), 0, 275);
  655. ExtUI::setTargetTemp_celsius(tempvalue, (ExtUI::extruder_t) ExtUI::E0);
  656. }
  657. else if (CodeSeen('C') && !ExtUI::isPrinting()) {
  658. if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10)
  659. ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS
  660. tempvalue = constrain(CodeValue(), 0, 275);
  661. ExtUI::setTargetTemp_celsius(tempvalue, (ExtUI::extruder_t) ExtUI::E0);
  662. }
  663. }
  664. break;
  665. case 17:// A17 set heated bed temp
  666. {
  667. unsigned int tempbed;
  668. if (CodeSeen('S')) {
  669. tempbed = constrain(CodeValue(), 0, 100);
  670. ExtUI::setTargetTemp_celsius(tempbed, (ExtUI::heater_t)ExtUI::BED);
  671. }
  672. }
  673. break;
  674. case 18:// A18 set fan speed
  675. {
  676. float fanPercent;
  677. if (CodeSeen('S')) {
  678. fanPercent = CodeValue();
  679. fanPercent = constrain(fanPercent, 0, 100);
  680. ExtUI::setTargetFan_percent(fanPercent, ExtUI::FAN0);
  681. }
  682. else {
  683. fanPercent = 100;
  684. }
  685. ExtUI::setTargetFan_percent(fanPercent, ExtUI::FAN0);
  686. SENDLINE_PGM("");
  687. }
  688. break;
  689. case 19: // A19 stop stepper drivers - sent on stop extrude command and on turn motors off command
  690. if (!ExtUI::isPrinting()) {
  691. quickstop_stepper();
  692. disable_all_steppers();
  693. }
  694. SENDLINE_PGM("");
  695. break;
  696. case 20: { // A20 read printing speed
  697. if (CodeSeen('S'))
  698. feedrate_percentage = constrain(CodeValue(), 40, 999);
  699. else
  700. SEND_PGM_VAL("A20V ", feedrate_percentage);
  701. }
  702. break;
  703. case 21: // A21 all home
  704. if (!ExtUI::isPrinting() && !ExtUI::isPrintingFromMediaPaused()) {
  705. if (CodeSeen('X') || CodeSeen('Y') || CodeSeen('Z')) {
  706. if (CodeSeen('X'))
  707. ExtUI::injectCommands_P(PSTR("G28 X"));
  708. if (CodeSeen('Y'))
  709. ExtUI::injectCommands_P(PSTR("G28 Y"));
  710. if (CodeSeen('Z'))
  711. ExtUI::injectCommands_P(PSTR("G28 Z"));
  712. }
  713. else if (CodeSeen('C')) {
  714. ExtUI::injectCommands_P(PSTR("G28"));
  715. }
  716. }
  717. break;
  718. case 22: // A22 move X/Y/Z or extrude
  719. if (!ExtUI::isPrinting()) {
  720. float coorvalue;
  721. unsigned int movespeed = 0;
  722. char commandStr[30];
  723. char fullCommandStr[38];
  724. commandStr[0] = 0; // empty string
  725. if (CodeSeen('F')) // Set feedrate
  726. movespeed = CodeValue();
  727. if (CodeSeen('X')) { // Move in X direction
  728. coorvalue = CodeValue();
  729. if ((coorvalue <= 0.2) && coorvalue > 0)
  730. sprintf_P(commandStr, PSTR("G1 X0.1F%i"), movespeed);
  731. else if ((coorvalue <= -0.1) && coorvalue > -1)
  732. sprintf_P(commandStr, PSTR("G1 X-0.1F%i"), movespeed);
  733. else
  734. sprintf_P(commandStr, PSTR("G1 X%iF%i"), int(coorvalue), movespeed);
  735. }
  736. else if (CodeSeen('Y')) { // Move in Y direction
  737. coorvalue = CodeValue();
  738. if ((coorvalue <= 0.2) && coorvalue > 0)
  739. sprintf_P(commandStr, PSTR("G1 Y0.1F%i"), movespeed);
  740. else if ((coorvalue <= -0.1) && coorvalue > -1)
  741. sprintf_P(commandStr, PSTR("G1 Y-0.1F%i"), movespeed);
  742. else
  743. sprintf_P(commandStr, PSTR("G1 Y%iF%i"), int(coorvalue), movespeed);
  744. }
  745. else if (CodeSeen('Z')) { // Move in Z direction
  746. coorvalue = CodeValue();
  747. if ((coorvalue <= 0.2) && coorvalue > 0)
  748. sprintf_P(commandStr, PSTR("G1 Z0.1F%i"), movespeed);
  749. else if ((coorvalue <= -0.1) && coorvalue > -1)
  750. sprintf_P(commandStr, PSTR("G1 Z-0.1F%i"), movespeed);
  751. else
  752. sprintf_P(commandStr, PSTR("G1 Z%iF%i"), int(coorvalue), movespeed);
  753. }
  754. else if (CodeSeen('E')) { // Extrude
  755. coorvalue = CodeValue();
  756. if ((coorvalue <= 0.2) && coorvalue > 0)
  757. sprintf_P(commandStr, PSTR("G1 E0.1F%i"), movespeed);
  758. else if ((coorvalue <= -0.1) && coorvalue > -1)
  759. sprintf_P(commandStr, PSTR("G1 E-0.1F%i"), movespeed);
  760. else
  761. sprintf_P(commandStr, PSTR("G1 E%iF500"), int(coorvalue));
  762. }
  763. if (strlen(commandStr) > 0) {
  764. sprintf_P(fullCommandStr, PSTR("G91\n%s\nG90"), commandStr);
  765. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  766. SERIAL_ECHOPGM("TFT Serial Debug: A22 Move final request with gcode... ");
  767. SERIAL_ECHOLN(fullCommandStr);
  768. #endif
  769. ExtUI::injectCommands(fullCommandStr);
  770. }
  771. }
  772. SENDLINE_PGM("");
  773. break;
  774. case 23: // A23 preheat pla
  775. if (!ExtUI::isPrinting()) {
  776. if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10)
  777. ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS
  778. ExtUI::setTargetTemp_celsius(PREHEAT_1_TEMP_BED, (ExtUI::heater_t) ExtUI::BED);
  779. ExtUI::setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, (ExtUI::extruder_t) ExtUI::E0);
  780. SENDLINE_PGM("OK");
  781. }
  782. break;
  783. case 24:// A24 preheat abs
  784. if (!ExtUI::isPrinting()) {
  785. if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10)
  786. ExtUI::injectCommands_P(PSTR("G1 Z10")); // RASE Z AXIS
  787. ExtUI::setTargetTemp_celsius(PREHEAT_2_TEMP_BED, (ExtUI::heater_t) ExtUI::BED);
  788. ExtUI::setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, (ExtUI::extruder_t) ExtUI::E0);
  789. SENDLINE_PGM("OK");
  790. }
  791. break;
  792. case 25: // A25 cool down
  793. if (!ExtUI::isPrinting()) {
  794. ExtUI::setTargetTemp_celsius(0, (ExtUI::heater_t) ExtUI::BED);
  795. ExtUI::setTargetTemp_celsius(0, (ExtUI::extruder_t) ExtUI::E0);
  796. SENDLINE_DBG_PGM("J12", "TFT Serial Debug: Cooling down... J12"); // J12 cool down
  797. }
  798. break;
  799. case 26: // A26 refresh SD
  800. #if ENABLED(SDSUPPORT)
  801. if (ExtUI::isMediaInserted()) {
  802. if (strlen(SelectedDirectory) > 0) {
  803. ExtUI::FileList currentFileList;
  804. if ((SelectedDirectory[0] == '.') && (SelectedDirectory[1] == '.')) {
  805. currentFileList.upDir();
  806. }
  807. else {
  808. if (SelectedDirectory[0] == '<')
  809. HandleSpecialMenu();
  810. else
  811. currentFileList.changeDir(SelectedDirectory);
  812. }
  813. }
  814. }
  815. else {
  816. SENDLINE_DBG_PGM("J02", "TFT Serial Debug: No SD Card mounted to refresh SD A26... J02");
  817. }
  818. SelectedDirectory[0] = 0;
  819. #endif
  820. break;
  821. #if ENABLED(SERVO_ENDSTOPS)
  822. case 27: break; // A27 servos angles adjust
  823. #endif
  824. case 28: // A28 filament test
  825. if (CodeSeen('O'))
  826. NOOP;
  827. else if (CodeSeen('C'))
  828. NOOP;
  829. SENDLINE_PGM("");
  830. break;
  831. case 33: // A33 get version info
  832. SEND_PGM("J33 ");
  833. SENDLINE_PGM(DETAILED_BUILD_VERSION);
  834. break;
  835. default:
  836. break;
  837. }
  838. }
  839. TFTbufindw = (TFTbufindw + 1) % TFTBUFSIZE;
  840. TFTbuflen += 1;
  841. serial3_count = 0; // clear buffer
  842. }
  843. else {
  844. TFTcmdbuffer[TFTbufindw][serial3_count++] = serial3_char;
  845. }
  846. }
  847. }
  848. void AnycubicTFTClass::DoSDCardStateCheck() {
  849. #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
  850. bool isInserted = ExtUI::isMediaInserted();
  851. if (isInserted)
  852. SENDLINE_DBG_PGM("J00", "TFT Serial Debug: SD card state changed... isInserted");
  853. else
  854. SENDLINE_DBG_PGM("J01", "TFT Serial Debug: SD card state changed... !isInserted");
  855. #endif
  856. }
  857. void AnycubicTFTClass::DoFilamentRunoutCheck() {
  858. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  859. // NOTE: ExtUI::getFilamentRunoutState() only returns the runout state if the job is printing
  860. // we want to actually check the status of the pin here, regardless of printstate
  861. if (READ(FIL_RUNOUT_PIN)) {
  862. if (mediaPrintingState == AMPRINTSTATE_PRINTING || mediaPrintingState == AMPRINTSTATE_PAUSED || mediaPrintingState == AMPRINTSTATE_PAUSE_REQUESTED) {
  863. // play tone to indicate filament is out
  864. ExtUI::injectCommands_P(PSTR("\nM300 P200 S1567\nM300 P200 S1174\nM300 P200 S1567\nM300 P200 S1174\nM300 P2000 S1567"));
  865. // tell the user that the filament has run out and wait
  866. SENDLINE_DBG_PGM("J23", "TFT Serial Debug: Blocking filament prompt... J23");
  867. }
  868. else {
  869. SENDLINE_DBG_PGM("J15", "TFT Serial Debug: Non blocking filament runout... J15");
  870. }
  871. }
  872. #endif // FILAMENT_RUNOUT_SENSOR
  873. }
  874. void AnycubicTFTClass::StartPrint() {
  875. #if ENABLED(SDSUPPORT)
  876. if (!ExtUI::isPrinting() && strlen(SelectedFile) > 0) {
  877. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  878. SERIAL_ECHOPGM("TFT Serial Debug: About to print file ... ");
  879. SERIAL_ECHO(ExtUI::isPrinting());
  880. SERIAL_ECHOPGM(" ");
  881. SERIAL_ECHOLN(SelectedFile);
  882. #endif
  883. mediaPrintingState = AMPRINTSTATE_PRINTING;
  884. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  885. ExtUI::printFile(SelectedFile);
  886. }
  887. #endif // SDUPPORT
  888. }
  889. void AnycubicTFTClass::PausePrint() {
  890. #if ENABLED(SDSUPPORT)
  891. if (ExtUI::isPrintingFromMedia() && mediaPrintingState != AMPRINTSTATE_STOP_REQUESTED && mediaPauseState == AMPAUSESTATE_NOT_PAUSED) {
  892. mediaPrintingState = AMPRINTSTATE_PAUSE_REQUESTED;
  893. mediaPauseState = AMPAUSESTATE_NOT_PAUSED; // need the userconfirm method to update pause state
  894. SENDLINE_DBG_PGM("J05", "TFT Serial Debug: SD print pause started... J05"); // J05 printing pause
  895. // for some reason pausing the print doesn't retract the extruder so force a manual one here
  896. ExtUI::injectCommands_P(PSTR("G91\nG1 E-2 F1800\nG90"));
  897. ExtUI::pausePrint();
  898. }
  899. #endif
  900. }
  901. void AnycubicTFTClass::ResumePrint() {
  902. #if ENABLED(SDSUPPORT)
  903. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  904. if (READ(FIL_RUNOUT_PIN)) {
  905. #if ENABLED(ANYCUBIC_LCD_DEBUG)
  906. SERIAL_ECHOLNPGM("TFT Serial Debug: Resume Print with filament sensor still tripped... ");
  907. #endif
  908. // trigger the user message box
  909. DoFilamentRunoutCheck();
  910. // re-enable the continue button
  911. SENDLINE_DBG_PGM("J18", "TFT Serial Debug: Resume Print with filament sensor still tripped... J18");
  912. return;
  913. }
  914. #endif
  915. if (mediaPauseState == AMPAUSESTATE_HEATER_TIMEOUT) {
  916. mediaPauseState = AMPAUSESTATE_REHEATING;
  917. // TODO: JBA I don't think J05 just disables the continue button, i think it injects a rogue M25. So taking this out
  918. // // disable the continue button
  919. // SENDLINE_DBG_PGM("J05", "TFT Serial Debug: Resume called with heater timeout... J05"); // J05 printing pause
  920. // reheat the nozzle
  921. ExtUI::setUserConfirmed();
  922. }
  923. else {
  924. mediaPrintingState = AMPRINTSTATE_PRINTING;
  925. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  926. SENDLINE_DBG_PGM("J04", "TFT Serial Debug: SD print resumed... J04"); // J04 printing form sd card now
  927. ExtUI::resumePrint();
  928. }
  929. #endif
  930. }
  931. void AnycubicTFTClass::StopPrint() {
  932. #if ENABLED(SDSUPPORT)
  933. mediaPrintingState = AMPRINTSTATE_STOP_REQUESTED;
  934. mediaPauseState = AMPAUSESTATE_NOT_PAUSED;
  935. SENDLINE_DBG_PGM("J16", "TFT Serial Debug: SD print stop called... J16");
  936. // for some reason stopping the print doesn't retract the extruder so force a manual one here
  937. ExtUI::injectCommands_P(PSTR("G91\nG1 E-2 F1800\nG90"));
  938. ExtUI::stopPrint();
  939. #endif
  940. }
  941. #endif // ANYCUBIC_LCD_I3MEGA