Prusa_farm.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #include "Prusa_farm.h"
  2. #include "macros.h"
  3. #include "Marlin.h"
  4. #include "cmdqueue.h"
  5. #include "temperature.h"
  6. #include "cardreader.h"
  7. #include "conv2str.h"
  8. #include "util.h"
  9. #include "ultralcd.h"
  10. #include "fsensor.h" //to be converted to Filament_sensor.h...
  11. #ifdef PRUSA_FARM
  12. #define PING_TIME 60 //time in s
  13. #define PING_TIME_LONG 600 //10 min; used when length of commands buffer > 0 to avoid 0 triggering when dealing with long gcodes
  14. #define PING_ALLERT_PERIOD 60 //time in s
  15. #define NC_TIME 10 //time in s for periodic important status messages sending which needs reponse from monitoring
  16. #define NC_BUTTON_LONG_PRESS 15 //time in s
  17. uint8_t farm_mode = 0;
  18. static ShortTimer NcTime;
  19. static uint8_t farm_timer = 8;
  20. static bool printer_connected = true;
  21. static unsigned long PingTime = 0;
  22. static uint8_t status_number = 0;
  23. static bool no_response = false;
  24. static uint8_t important_status;
  25. static void prusa_statistics_err(char c);
  26. static void prusa_stat_printerstatus(uint8_t _status);
  27. static void prusa_stat_farm_number();
  28. static void prusa_stat_diameter();
  29. static void prusa_stat_temperatures();
  30. static void prusa_stat_printinfo();
  31. static void lcd_send_status();
  32. #ifdef FARM_CONNECT_MESSAGE
  33. static void proc_commands();
  34. static void lcd_connect_printer();
  35. #endif //FARM_CONNECT_MESSAGE
  36. static void lcd_ping();
  37. static void prusa_statistics_err(char c) {
  38. SERIAL_ECHOPGM("{[ERR:");
  39. SERIAL_ECHO(c);
  40. SERIAL_ECHO(']');
  41. prusa_stat_farm_number();
  42. }
  43. static void prusa_statistics_case0(uint8_t statnr) {
  44. SERIAL_ECHO('{');
  45. prusa_stat_printerstatus(statnr);
  46. prusa_stat_farm_number();
  47. prusa_stat_printinfo();
  48. }
  49. static void prusa_stat_printerstatus(uint8_t _status) {
  50. SERIAL_ECHOPGM("[PRN:");
  51. SERIAL_ECHO(_status);
  52. SERIAL_ECHO(']');
  53. }
  54. static void prusa_stat_farm_number() {
  55. SERIAL_ECHOPGM("[PFN:0]");
  56. }
  57. static void prusa_stat_diameter() {
  58. SERIAL_ECHOPGM("[DIA:");
  59. SERIAL_ECHO(eeprom_read_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM));
  60. SERIAL_ECHO(']');
  61. }
  62. static void prusa_stat_temperatures() {
  63. SERIAL_ECHOPGM("[ST0:");
  64. SERIAL_ECHO(target_temperature[0]);
  65. SERIAL_ECHOPGM("][STB:");
  66. SERIAL_ECHO(target_temperature_bed);
  67. SERIAL_ECHOPGM("][AT0:");
  68. SERIAL_ECHO(current_temperature[0]);
  69. SERIAL_ECHOPGM("][ATB:");
  70. SERIAL_ECHO(current_temperature_bed);
  71. SERIAL_ECHO(']');
  72. }
  73. static void prusa_stat_printinfo() {
  74. SERIAL_ECHOPGM("[TFU:");
  75. SERIAL_ECHO(total_filament_used);
  76. SERIAL_ECHOPGM("][PCD:");
  77. SERIAL_ECHO(itostr3(card.percentDone()));
  78. SERIAL_ECHOPGM("][FEM:");
  79. SERIAL_ECHO(itostr3(feedmultiply));
  80. SERIAL_ECHOPGM("][FNM:");
  81. SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename);
  82. SERIAL_ECHOPGM("][TIM:");
  83. if (starttime != 0) {
  84. SERIAL_ECHO(_millis() / 1000 - starttime / 1000);
  85. }
  86. else {
  87. SERIAL_ECHO(0);
  88. }
  89. SERIAL_ECHOPGM("][FWR:");
  90. SERIAL_ECHORPGM(FW_VERSION_STR_P());
  91. SERIAL_ECHO(']');
  92. prusa_stat_diameter();
  93. }
  94. static void lcd_send_status() {
  95. if (farm_mode && no_response && (NcTime.expired(NC_TIME * 1000))) {
  96. //send important status messages periodicaly
  97. prusa_statistics(important_status);
  98. NcTime.start();
  99. #ifdef FARM_CONNECT_MESSAGE
  100. lcd_connect_printer();
  101. #endif //FARM_CONNECT_MESSAGE
  102. }
  103. }
  104. #ifdef FARM_CONNECT_MESSAGE
  105. static void proc_commands() {
  106. if (buflen) {
  107. process_commands();
  108. if (!cmdbuffer_front_already_processed)
  109. cmdqueue_pop_front();
  110. cmdbuffer_front_already_processed = false;
  111. }
  112. }
  113. static void lcd_connect_printer() {
  114. lcd_update_enable(false);
  115. lcd_clear();
  116. int i = 0;
  117. int t = 0;
  118. lcd_puts_at_P(0, 0, PSTR("Connect printer to"));
  119. lcd_puts_at_P(0, 1, PSTR("monitoring or hold"));
  120. lcd_puts_at_P(0, 2, PSTR("the knob to continue"));
  121. while (no_response) {
  122. i++;
  123. t++;
  124. delay_keep_alive(100);
  125. proc_commands();
  126. if (t == 10) {
  127. prusa_statistics(important_status);
  128. t = 0;
  129. }
  130. if (READ(BTN_ENC)) { //if button is not pressed
  131. i = 0;
  132. lcd_puts_at_P(0, 3, PSTR(" "));
  133. }
  134. if (i != 0)
  135. lcd_putc_at((i * 20) / (NC_BUTTON_LONG_PRESS * 10), 3, LCD_STR_SOLID_BLOCK[0]);
  136. if (i == NC_BUTTON_LONG_PRESS * 10)
  137. no_response = false;
  138. }
  139. lcd_update_enable(true);
  140. lcd_update(2);
  141. }
  142. #endif //FARM_CONNECT_MESSAGE
  143. static void lcd_ping() { //chceck if printer is connected to monitoring when in farm mode
  144. if (farm_mode) {
  145. bool empty = cmd_buffer_empty();
  146. if ((_millis() - PingTime) * 0.001 > (empty ? PING_TIME : PING_TIME_LONG)) {
  147. //if commands buffer is empty use shorter time period
  148. //if there are comamnds in buffer, some long gcodes can delay execution of ping command
  149. //therefore longer period is used
  150. printer_connected = false;
  151. }
  152. else {
  153. printer_connected = true;
  154. }
  155. }
  156. }
  157. void prusa_statistics(uint8_t _message) {
  158. const uint8_t _fil_nr = 0;
  159. if (!farm_mode)
  160. return;
  161. switch (_message) {
  162. case 0: // default message
  163. if (busy_state == PAUSED_FOR_USER) {
  164. prusa_statistics_case0(15);
  165. }
  166. else if (isPrintPaused) {
  167. prusa_statistics_case0(14);
  168. }
  169. else if (IS_SD_PRINTING || loading_flag) {
  170. prusa_statistics_case0(4);
  171. }
  172. else {
  173. SERIAL_ECHO('{');
  174. prusa_stat_printerstatus(1);
  175. prusa_stat_farm_number();
  176. prusa_stat_diameter();
  177. status_number = 1;
  178. }
  179. break;
  180. case 1: // 1 heating
  181. SERIAL_ECHO('{');
  182. prusa_stat_printerstatus(2);
  183. prusa_stat_farm_number();
  184. status_number = 2;
  185. farm_timer = 1;
  186. break;
  187. case 2: // heating done
  188. SERIAL_ECHO('{');
  189. prusa_stat_printerstatus(3);
  190. prusa_stat_farm_number();
  191. SERIAL_ECHOLN('}');
  192. status_number = 3;
  193. farm_timer = 1;
  194. if (IS_SD_PRINTING || loading_flag) {
  195. SERIAL_ECHO('{');
  196. prusa_stat_printerstatus(4);
  197. prusa_stat_farm_number();
  198. status_number = 4;
  199. }
  200. else {
  201. SERIAL_ECHO('{');
  202. prusa_stat_printerstatus(3);
  203. prusa_stat_farm_number();
  204. status_number = 3;
  205. }
  206. farm_timer = 1;
  207. break;
  208. case 3: // filament change
  209. // must do a return here to prevent doing SERIAL_ECHOLN("}") at the very end of this function
  210. // saved a considerable amount of FLASH
  211. return;
  212. break;
  213. case 4: // print succesfull
  214. SERIAL_ECHOPGM("{[RES:1][FIL:");
  215. MYSERIAL.print(int(_fil_nr));
  216. SERIAL_ECHO(']');
  217. prusa_stat_printerstatus(status_number);
  218. prusa_stat_farm_number();
  219. farm_timer = 2;
  220. break;
  221. case 5: // print not succesfull
  222. SERIAL_ECHOPGM("{[RES:0][FIL:");
  223. MYSERIAL.print(int(_fil_nr));
  224. SERIAL_ECHO(']');
  225. prusa_stat_printerstatus(status_number);
  226. prusa_stat_farm_number();
  227. farm_timer = 2;
  228. break;
  229. case 6: // print done
  230. SERIAL_ECHOPGM("{[PRN:8]");
  231. prusa_stat_farm_number();
  232. status_number = 8;
  233. farm_timer = 2;
  234. break;
  235. case 7: // print done - stopped
  236. SERIAL_ECHOPGM("{[PRN:9]");
  237. prusa_stat_farm_number();
  238. status_number = 9;
  239. farm_timer = 2;
  240. break;
  241. case 8: // printer started
  242. SERIAL_ECHOPGM("{[PRN:0]");
  243. prusa_stat_farm_number();
  244. status_number = 0;
  245. farm_timer = 2;
  246. break;
  247. case 20: // echo farm no
  248. SERIAL_ECHO('{');
  249. prusa_stat_printerstatus(status_number);
  250. prusa_stat_farm_number();
  251. farm_timer = 4;
  252. break;
  253. case 21: // temperatures
  254. SERIAL_ECHO('{');
  255. prusa_stat_temperatures();
  256. prusa_stat_farm_number();
  257. prusa_stat_printerstatus(status_number);
  258. break;
  259. case 22: // waiting for filament change
  260. SERIAL_ECHOPGM("{[PRN:5]");
  261. prusa_stat_farm_number();
  262. status_number = 5;
  263. break;
  264. case 90: // Error - Thermal Runaway
  265. prusa_statistics_err('1');
  266. break;
  267. case 91: // Error - Thermal Runaway Preheat
  268. prusa_statistics_err('2');
  269. break;
  270. case 92: // Error - Min temp
  271. prusa_statistics_err('3');
  272. break;
  273. case 93: // Error - Max temp
  274. prusa_statistics_err('4');
  275. break;
  276. case 99: // heartbeat
  277. SERIAL_ECHOPGM("{[PRN:99]");
  278. prusa_stat_temperatures();
  279. prusa_stat_farm_number();
  280. break;
  281. }
  282. SERIAL_ECHOLN('}');
  283. }
  284. void prusa_statistics_update_from_status_screen() {
  285. if (farm_mode) {
  286. farm_timer--;
  287. if (farm_timer < 1) {
  288. farm_timer = 10;
  289. prusa_statistics(0);
  290. }
  291. switch (farm_timer) {
  292. case 8:
  293. prusa_statistics(21);
  294. if(loading_flag)
  295. prusa_statistics(22);
  296. break;
  297. case 5:
  298. if (IS_SD_PRINTING)
  299. prusa_statistics(20);
  300. break;
  301. }
  302. }
  303. }
  304. void prusa_statistics_update_from_lcd_update() {
  305. lcd_ping(); //check that we have received ping command if we are in farm mode
  306. lcd_send_status();
  307. }
  308. void farm_mode_init() {
  309. farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE);
  310. if (farm_mode == 0xFF) {
  311. farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode
  312. eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode);
  313. }
  314. else if (farm_mode) {
  315. no_response = true; //we need confirmation by recieving PRUSA thx
  316. important_status = 8;
  317. prusa_statistics(8);
  318. #ifdef HAS_SECOND_SERIAL_PORT
  319. selectedSerialPort = 1;
  320. #endif //HAS_SECOND_SERIAL_PORT
  321. MYSERIAL.begin(BAUDRATE);
  322. #ifdef FILAMENT_SENSOR
  323. //to be converted to Filament_sensor.h...
  324. //disabled filament autoload (PFW360)
  325. fsensor_autoload_set(false);
  326. #endif //FILAMENT_SENSOR
  327. // ~ FanCheck -> on
  328. eeprom_update_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED, true);
  329. }
  330. }
  331. bool farm_prusa_code_seen() {
  332. if (!farm_mode)
  333. return false;
  334. if (code_seen_P(PSTR("Ping"))) { // PRUSA Ping
  335. PingTime = _millis();
  336. }
  337. else if (code_seen_P(PSTR("PRN"))) { // PRUSA PRN
  338. printf_P(_N("%u"), status_number);
  339. }
  340. else if (code_seen_P(PSTR("thx"))) { // PRUSA thx
  341. no_response = false;
  342. }
  343. else {
  344. return false;
  345. }
  346. return true;
  347. }
  348. void farm_gcode_g98() {
  349. farm_mode = 1;
  350. PingTime = _millis();
  351. eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode);
  352. SilentModeMenu = SILENT_MODE_OFF;
  353. eeprom_update_byte((unsigned char *)EEPROM_SILENT, SilentModeMenu);
  354. fCheckModeInit(); // alternatively invoke printer reset
  355. }
  356. void farm_gcode_g99() {
  357. farm_mode = 0;
  358. printer_connected = true;
  359. eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode);
  360. lcd_update(2);
  361. fCheckModeInit(); // alternatively invoke printer reset
  362. }
  363. #else //PRUSA_FARM
  364. void prusa_statistics(_UNUSED uint8_t message) {
  365. }
  366. void prusa_statistics_update_from_status_screen() {
  367. }
  368. void prusa_statistics_update_from_lcd_update() {
  369. }
  370. void farm_mode_init() {
  371. }
  372. bool farm_prusa_code_seen() {
  373. return false;
  374. }
  375. void farm_gcode_g98() {
  376. }
  377. void farm_gcode_g99() {
  378. }
  379. #endif //PRUSA_FARM