From b4e2b4f00103c0473c79903a8d675ffd9f497fe8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 18 Jan 2023 22:28:25 -0600 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20Ender-5=20S1=20added=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration.h | 10 ++++++++++ Marlin/Configuration_adv.h | 3 +++ Marlin/src/inc/Conditionals-2-LCD.h | 2 +- Marlin/src/inc/Conditionals-4-adv.h | 2 +- Marlin/src/inc/Conditionals-5-post.h | 4 ++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index a443d4b302..4d23f8d4d8 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -3182,6 +3182,12 @@ // //#define CR10_STOCKDISPLAY +// Resistive touch screen +//#define CREALITY_RTS + +// Creality Cloud-based Printing +//#define CREALITY_CLOUD + // // Ender-2 OEM display, a variant of the MKS_MINI_12864 // @@ -3768,3 +3774,7 @@ // Disable servo with M282 to reduce power consumption, noise, and heat when not in use //#define SERVO_DETACH_GCODE + +// Creality WiFi +//#define CREALITY_WIFI +//#define MENU_RESET_WIFI diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index e46a3af2de..5fa342982b 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1030,6 +1030,9 @@ #define BLTOUCH_HS_EXTRA_CLEARANCE 7 // Extra Z Clearance #endif + // Add a Z limit + //#define BLTOUCH_AND_Z_LIMIT + #endif // BLTOUCH // @section calibrate diff --git a/Marlin/src/inc/Conditionals-2-LCD.h b/Marlin/src/inc/Conditionals-2-LCD.h index 72bad45c89..cc0330150d 100644 --- a/Marlin/src/inc/Conditionals-2-LCD.h +++ b/Marlin/src/inc/Conditionals-2-LCD.h @@ -667,7 +667,7 @@ #if !HAS_MARLINUI_HD44780 #undef LCD_INFO_SCREEN_STYLE #endif -#if NONE(HAS_MARLINUI_HD44780, HAS_MARLINUI_U8GLIB, HAS_TFT_LVGL_UI, TFT_COLOR_UI, DGUS_LCD_UI_E3S1PRO) +#if NONE(HAS_MARLINUI_HD44780, HAS_MARLINUI_U8GLIB, HAS_TFT_LVGL_UI, TFT_COLOR_UI, DGUS_LCD_UI_E3S1PRO, CREALITY_RTS) #undef LCD_LANGUAGE #endif #if DISABLED(MPC_AUTOTUNE) diff --git a/Marlin/src/inc/Conditionals-4-adv.h b/Marlin/src/inc/Conditionals-4-adv.h index 036e426de6..f87555bc0c 100644 --- a/Marlin/src/inc/Conditionals-4-adv.h +++ b/Marlin/src/inc/Conditionals-4-adv.h @@ -1099,7 +1099,7 @@ #if ANY(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) #define HAS_SOFTWARE_ENDSTOPS 1 #endif -#if ANY(EXTENSIBLE_UI, IS_NEWPANEL, EMERGENCY_PARSER, HAS_ADC_BUTTONS, HAS_DWIN_E3V2) +#if ANY(EXTENSIBLE_UI, IS_NEWPANEL, EMERGENCY_PARSER, HAS_ADC_BUTTONS, HAS_DWIN_E3V2, CREALITY_RTS) #define HAS_RESUME_CONTINUE 1 #endif diff --git a/Marlin/src/inc/Conditionals-5-post.h b/Marlin/src/inc/Conditionals-5-post.h index 024eb42f51..0a85f64036 100644 --- a/Marlin/src/inc/Conditionals-5-post.h +++ b/Marlin/src/inc/Conditionals-5-post.h @@ -3180,7 +3180,7 @@ #define HAS_TEMPERATURE 1 #endif -#if HAS_TEMPERATURE && ANY(HAS_MARLINUI_MENU, HAS_DWIN_E3V2, HAS_DGUS_LCD_CLASSIC) +#if HAS_TEMPERATURE && ANY(HAS_MARLINUI_MENU, HAS_DWIN_E3V2, HAS_DGUS_LCD_CLASSIC, CREALITY_RTS) #ifdef PREHEAT_10_LABEL #define PREHEAT_COUNT 10 #elif defined(PREHEAT_9_LABEL) @@ -3330,7 +3330,7 @@ * Advanced Pause - Filament Change */ #if ENABLED(ADVANCED_PAUSE_FEATURE) - #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI, SOVOL_SV06_RTS) || ALL(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) + #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI, SOVOL_SV06_RTS, CREALITY_RTS) || ALL(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) #define M600_PURGE_MORE_RESUMABLE 1 // UI provides some way to Purge More / Resume #endif #ifndef FILAMENT_CHANGE_SLOW_LOAD_LENGTH From 9504e5164739c5c943997df84c0a168ab3a55b6e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 14 Feb 2023 00:46:57 -0600 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20Ender-5=20S1=20added=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/bedlevel/abl/M2900.cpp | 45 + Marlin/src/gcode/feature/leds/M224_M225.cpp | 40 + Marlin/src/gcode/gcode.cpp | 25 + Marlin/src/gcode/gcode.h | 26 + Marlin/src/gcode/host/M194.cpp | 46 + Marlin/src/gcode/stats/M72.cpp | 52 + Marlin/src/gcode/stats/M79.cpp | 41 + Marlin/src/gcode/wifi/M930.cpp | 58 + Marlin/src/lcd/rts/lcd_rts.cpp | 3516 +++++++++++++++++++ Marlin/src/lcd/rts/lcd_rts.h | 701 ++++ ini/features.ini | 3 + platformio.ini | 7 +- 12 files changed, 4559 insertions(+), 1 deletion(-) create mode 100644 Marlin/src/gcode/bedlevel/abl/M2900.cpp create mode 100644 Marlin/src/gcode/feature/leds/M224_M225.cpp create mode 100644 Marlin/src/gcode/host/M194.cpp create mode 100644 Marlin/src/gcode/stats/M72.cpp create mode 100644 Marlin/src/gcode/stats/M79.cpp create mode 100644 Marlin/src/gcode/wifi/M930.cpp create mode 100644 Marlin/src/lcd/rts/lcd_rts.cpp create mode 100755 Marlin/src/lcd/rts/lcd_rts.h diff --git a/Marlin/src/gcode/bedlevel/abl/M2900.cpp b/Marlin/src/gcode/bedlevel/abl/M2900.cpp new file mode 100644 index 0000000000..c3699e5a07 --- /dev/null +++ b/Marlin/src/gcode/bedlevel/abl/M2900.cpp @@ -0,0 +1,45 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(CREALITY_RTS) + +#include "../../gcode.h" +#include "../../../feature/bedlevel/bedlevel.h" +#include "../../../lcd/rts/lcd_rts.h" + +#define DIMLFAC1 (0.8f) +#define DIMLFAC2 ((1.0f - DIMLFAC1) / 2.0f) // 0.1 + +/** + * M2900: Report Bed Leveling Grid and test result + */ +void GcodeSuite::M2900() { + bedlevel.print_leveling_grid(); + const float z_valuesTest = DIMLFAC1 * bedlevel.z_values[0][0] + + DIMLFAC2 * ( (bedlevel.z_values[0][1] + bedlevel.z_values[1][0]) * 2.0f + - (bedlevel.z_values[0][2] + bedlevel.z_values[2][0]) ); + SERIAL_ECHOLNPGM("z_valuesTest = ", z_valuesTest, " algorithm"); +} + +#endif // CREALITY_RTS diff --git a/Marlin/src/gcode/feature/leds/M224_M225.cpp b/Marlin/src/gcode/feature/leds/M224_M225.cpp new file mode 100644 index 0000000000..6d0abdac46 --- /dev/null +++ b/Marlin/src/gcode/feature/leds/M224_M225.cpp @@ -0,0 +1,40 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(CREALITY_RTS) + +#include "../../gcode.h" +#include "../../../lcd/rts/lcd_rts.h" + +/** + * M224: LED On + */ +void GcodeSuite::M224() { RTS_SetLED(true); } + +/** + * M225: LED Off + */ +void GcodeSuite::M225() { RTS_SetLED(false); } + +#endif // CREALITY_RTS diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 10a6f3d65b..8b35400c52 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -562,6 +562,13 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) { case 48: M48(); break; // M48: Z probe repeatability test #endif + #if ENABLED(CREALITY_RTS) + #if HAS_MEDIA + case 72: M72(); break; // M72: Cloud print filename + #endif + case 79: M79(); break; // M79: Cloud print statistics + #endif + #if ENABLED(SET_PROGRESS_MANUALLY) case 73: M73(); break; // M73: Set progress percentage #endif @@ -765,6 +772,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) { case 221: M221(); break; // M221: Set Flow Percentage #endif + #if ENABLED(CREALITY_RTS) + case 224: M224(); break; // M224: LED On + case 225: M225(); break; // M225: LED Off + #endif + #if ENABLED(DIRECT_PIN_CONTROL) case 226: M226(); break; // M226: Wait until a pin reaches a state #endif @@ -1132,6 +1144,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) { case 997: M997(); break; // M997: Perform in-application firmware update #endif + #if ENABLED(CREALITY_WIFI) + case 930: M930(); break; // M930: Support Creality WIFI Box + case 194: M194(); break; + #endif + case 999: M999(); break; // M999: Restart after being Stopped #if ENABLED(POWER_LOSS_RECOVERY) @@ -1155,6 +1172,10 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) { case 1004: M1004(); break; // M1004: UBL Mesh Wizard #endif + #if ENABLED(CREALITY_RTS) + case 2900: M2900(); break; // M2900: Report Bed Leveling Grid and test result + #endif + #if ENABLED(MAX7219_GCODE) case 7219: M7219(); break; // M7219: Set LEDs, columns, and rows #endif @@ -1259,6 +1280,10 @@ void GcodeSuite::process_subcommands_now(char * gcode) { #if ENABLED(HOST_KEEPALIVE_FEATURE) + #if ENABLED(CREALITY_RTS) + extern int change_page_font; + #endif + /** * Output a "busy" message at regular intervals * while the machine is not accepting commands. diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 378a1a73f4..c969641dd1 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -114,11 +114,13 @@ * M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins (Requires PINS_DEBUGGING) * M48 - Measure Z Probe repeatability: M48 P X Y V E L S. (Requires Z_MIN_PROBE_REPEATABILITY_TEST) * + * M72 - Cloud print filename; * M73 - Set the progress percentage. (Requires SET_PROGRESS_MANUALLY) * M75 - Start the print job timer. * M76 - Pause the print job timer. * M77 - Stop the print job timer. * M78 - Show statistical information about the print jobs. (Requires PRINTCOUNTER) + * M79 - Cloud print statistics.S0:cloud connect; S1:cloud print start; S2:cloud print pause; S3:cloud print resume; S4:cloud print stop; S5:cloud print complete * * M80 - Turn on Power Supply. (Requires PSU_CONTROL) * M81 - Turn off Power Supply. (Requires PSU_CONTROL) @@ -204,6 +206,8 @@ * M220 - Set Feedrate Percentage: 'M220 S' (i.e., "FR" on the LCD) * Use 'M220 B' to back up the Feedrate Percentage and 'M220 R' to restore it. (Requires an MMU_MODEL version 2 or 2S) * M221 - Set Flow Percentage: 'M221 S' (Requires an extruder) + * M224 - LED On + * M225 - LED Off * M226 - Wait until a pin is in a given state: 'M226 P S' (Requires DIRECT_PIN_CONTROL) * M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE) * M250 - Set LCD contrast: 'M250 C' (0-63). (Requires LCD support) @@ -324,6 +328,7 @@ * M919 - Set / Report motor Chopper Times (time_off, hysteresis_end, hysteresis_start) using axis codes XYZE, etc. * If no parameters are given, report. (Requires *_DRIVER_TYPE TMC(2130|2160|5130|5160|2208|2209|2240|2660)) * M920 - Set Homing Current. (Requires distinct *_CURRENT_HOME settings) + * M930 - Wi-Fi ON/OFF status. * M936 - OTA update firmware. (Requires OTA_FIRMWARE_UPDATE) * M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER) * M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC) @@ -730,6 +735,13 @@ private: static void M48(); #endif + #if ENABLED(CREALITY_RTS) + #if HAS_MEDIA + static void M72(); + #endif + static void M79(); + #endif + #if ENABLED(SET_PROGRESS_MANUALLY) static void M73(); #endif @@ -950,6 +962,11 @@ private: static void M221(); #endif + #if ENABLED(CREALITY_RTS) + static void M224(); + static void M225(); + #endif + #if ENABLED(DIRECT_PIN_CONTROL) static void M226(); #endif @@ -1313,6 +1330,11 @@ private: static void M928(); #endif + #if ENABLED(CREALITY_WIFI) + static void M930(); + static void M194(); + #endif + #if ENABLED(OTA_FIRMWARE_UPDATE) static void M936(); #endif @@ -1363,6 +1385,10 @@ private: static void M1004(); #endif + #if ENABLED(CREALITY_RTS) + static void M2900(); + #endif + #if ENABLED(HAS_MCP3426_ADC) static void M3426(); #endif diff --git a/Marlin/src/gcode/host/M194.cpp b/Marlin/src/gcode/host/M194.cpp new file mode 100644 index 0000000000..a063edeec3 --- /dev/null +++ b/Marlin/src/gcode/host/M194.cpp @@ -0,0 +1,46 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(MENU_RESET_WIFI) + +#include "../gcode.h" +#include "../../MarlinCore.h" + +#if ENABLED(CREALITY_RTS) + #include "../../../src/lcd/rts/lcd_rts.h" +#endif + +/** + * M194: Reset WiFi Module + */ +void GcodeSuite::M194() { + TERN_(CREALITY_RTS, if (parser.seen('S')) wifi_enable_flag = parser.boolval('S')); + + // record pressed state and output low level + rts_wifi_state = PRESSED; + OUT_WRITE(RESET_WIFI_PIN, LOW); + SERIAL_ECHOLNPGM(STR_OK " wifi is resetting"); +} + +#endif // MENU_RESET_WIFI diff --git a/Marlin/src/gcode/stats/M72.cpp b/Marlin/src/gcode/stats/M72.cpp new file mode 100644 index 0000000000..edf9c44ce1 --- /dev/null +++ b/Marlin/src/gcode/stats/M72.cpp @@ -0,0 +1,52 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ALL(HAS_MEDIA, CREALITY_RTS) + +#include "../gcode.h" +#include "../../sd/cardreader.h" +#include "../../lcd/marlinui.h" +#include "../../lcd/rts/lcd_rts.h" + +#if HAS_FILAMENT_SENSOR + #include "../../feature/runout.h" +#endif + +/** + * M72: Open a file + * + * The path is relative to the root directory + */ +void GcodeSuite::M72() { + // Simplify3D includes the size, so zero out all spaces (#7227) + for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0'; + + card.openFileRead(parser.string_arg); + + RTS_OpenFileCloud(); + + TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0)); +} + +#endif // HAS_MEDIA && CREALITY_RTS diff --git a/Marlin/src/gcode/stats/M79.cpp b/Marlin/src/gcode/stats/M79.cpp new file mode 100644 index 0000000000..fe10d3191e --- /dev/null +++ b/Marlin/src/gcode/stats/M79.cpp @@ -0,0 +1,41 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(CREALITY_RTS) + +#include "../gcode.h" + +#include "../../lcd/rts/lcd_rts.h" + +/** + * M79: cloud print statistics + */ +void GcodeSuite::M79() { + if (parser.seenval('S')) RTS_CloudCommand(cloudCommand_t(parser.value_int())); + if (parser.seenval('T')) RTS_SetStatsFR(parser.value_feedrate()); + if (parser.seenval('C')) RTS_SetStatsTime(parser.value_celsius()); + if (parser.seenval('D')) RTS_SetStatsRemain(parser.value_celsius()); +} + +#endif // CREALITY_RTS diff --git a/Marlin/src/gcode/wifi/M930.cpp b/Marlin/src/gcode/wifi/M930.cpp new file mode 100644 index 0000000000..7d120a98cd --- /dev/null +++ b/Marlin/src/gcode/wifi/M930.cpp @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(CREALITY_WIFI) + +#include "../gcode.h" +#include "../../lcd/rts/lcd_rts.h" + +/** + * M930: WIFI Box Function + */ +void GcodeSuite::M930() { + if (parser.boolval('F')) { + switch (parser.intval('S')) { + case 1: + if (flag_counter_wifi_reset) { + flag_counter_wifi_reset = false; + rts.sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + } + rts.sendData(1, WIFI_CONNECTED_DISPLAY_ICON_VP); + break; + + case 2: + rts.sendData(0, ADV_SETTING_WIFI_ICON_VP); + rts.sendData(1, WIFI_CONNECTED_DISPLAY_ICON_VP); + break; + + case 3: + rts.sendData(1, ADV_SETTING_WIFI_ICON_VP); + rts.sendData(0, WIFI_CONNECTED_DISPLAY_ICON_VP); + break; + } + } +} + +#endif // CREALITY_WIFI diff --git a/Marlin/src/lcd/rts/lcd_rts.cpp b/Marlin/src/lcd/rts/lcd_rts.cpp new file mode 100644 index 0000000000..d552c253e0 --- /dev/null +++ b/Marlin/src/lcd/rts/lcd_rts.cpp @@ -0,0 +1,3516 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Resistive Touch Screen + * Copyright (c) 2023 Creality3D + */ +#include "../../inc/MarlinConfig.h" + +#if ENABLED(CREALITY_RTS) + +#include "lcd_rts.h" + +#include "../marlinui.h" // For material_preset +#include "../../MarlinCore.h" +#include "../../feature/powerloss.h" +#include "../../feature/babystep.h" +#include "../../module/temperature.h" +#include "../../module/printcounter.h" +#include "../../module/planner.h" +#include "../../gcode/queue.h" +#include "../../gcode/gcode.h" + +#if HAS_BED_PROBE + #include "../../module/probe.h" +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #include "../../feature/runout.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + #include "../../feature/bedlevel/bedlevel.h" +#endif + +#if ENABLED(EEPROM_SETTINGS) + #include "../../HAL/shared/eeprom_api.h" + #include "../../module/settings.h" +#endif + +//#define DEBUG_OUT 1 +#include "../../core/debug_out.h" + +#if ENABLED(MENU_RESET_WIFI) + wifi_state_t rts_wifi_state = INITIAL; +#endif + +char errorway = 0; +char errornum = 0; +char home_errornum = 0; +char error_sd_num = 0; + +#if ENABLED(BABYSTEPPING) + float zprobe_zoffset; + float last_zoffset = 0.0; +#endif + +bool power_off_type_yes = false; + +int8_t g_cloudPLRStatusValue = 0; // Cloud printing status flag + +const float manual_feedrate_mm_m[] = { 50 * 60, 50 * 60, 4 * 60, 60 }; +constexpr float default_max_feedrate[] = DEFAULT_MAX_FEEDRATE; +constexpr float default_max_acceleration[] = DEFAULT_MAX_ACCELERATION; +constexpr float default_max_jerk[] = { DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK }; +constexpr float default_axis_steps_per_unit[] = DEFAULT_AXIS_STEPS_PER_UNIT; + +float default_nozzle_ptemp = DEFAULT_KP, + default_nozzle_itemp = DEFAULT_KI, + default_nozzle_dtemp = DEFAULT_KD; + +float default_hotbed_ptemp = DEFAULT_BED_KP, + default_hotbed_itemp = DEFAULT_BED_KI, + default_hotbed_dtemp = DEFAULT_BED_KD; + +int startprogress = 0; +CRec CardRecbuf; +int16_t temphot = 0; +int16_t tempbed = 0; +float temp_bed_display = 0; +uint8_t afterprobe_fan0_speed = 0; +float pause_e = 0; +extern bool sd_printing_autopause; // gcode/queue.cpp +extern bool SD_Card_status; // gcode/queue.cpp +bool sdcard_pause_check = true; +bool pause_action_flag = false; +bool print_preheat_check = false; +bool probe_offset_flag = false; + +float ChangeFilamentTemp = 200; +millis_t next_rts_update_ms = 0; +millis_t next_shutdown_update_ms = 0; +millis_t next_wifireset_update_ms = 0; +unsigned int count_ms = 0; +unsigned int wifiresetcount_ms = 0; +unsigned long count_lcd_down = 0; +bool flag_lcd_down = false; + +int last_target_temperature[4] = { 0 }; +int last_target_temperature_bed; +uint8_t waitway = 0; +int change_page_font = 1; +unsigned char Percentrecord = 0; +// represents to update file list +bool CardUpdate = false; + +uint8_t fileCnt = 0; +uint8_t file_current_page = 1; +uint8_t file_total_page = 1; +uint8_t page_total_file = 0; + +float RTS::zCoordinateOffset; // Z-axis space coordinate difference +DB RTS::recdat; +DB RTS::snddat; +unsigned char RTS::databuf[RTS_DATA_SIZE]; + +RTS rts; + +// represents SD-card status, true means SD is available, false means opposite. +bool lcd_sd_status; + +char Checkfilenum = 0; +char cmdbuf[20] = { 0 }; +float FilamentLOAD = 10; +float FilamentUnLOAD = 10; + +// 1 for 10mm, 2 for 1mm, 3 for 0.1mm +unsigned char AxisUnitMode; +float axis_unit = 10.0; +bool LEDStatus = false; + +bool wifi_enable_flag; + +int update_time_value = 0; + +bool PoweroffContinue = false; +char commandbuf[30]; + +uint16_t remain_time = 0; + +bool G29_flag = false; +bool G29_finished = false; +float z_values_value[4][4] = { 0 }; +bool leveling_flag = false; +bool flag_counter_wifi_reset = false; +HMI_LCD_Flag_t HMI_lcd_flag{0}; + +static bool temp_remove_card_flag = false; +//static bool temp_cutting_line_flag = false; +//static bool temp_wifi_print_flag = false; // 0 No interruption, 1 Suspension of material breaking 2 Suspension of card pulling + +BedNozzleHeightCalSt st_bedNozzleHeightCal = { 0 }; // Platform and Nozzle Height Measuring Structure +float bedNozzleHeightCalZ = 0; // Platform nozzle Z-axis measurement variable +bool g_heaterLoadTempAdd = false; // Inlet and out material temperature heating +bool g_uiXYAxisEnable = false; // Axis movement interface, YX axis motor enable flag bit +bool g_uiZAxisEnable = false; // Axis movement interface, Z-axis motor enable flag + +// Monitor SD card eject +static void Remove_card_window_check() { + static bool lSDCardStatus = false; + // SD card inserted + if (!lSDCardStatus && card.isSDCardInserted()) { // have card + lSDCardStatus = true; + } + // SD card removed + else if (lSDCardStatus && !card.isSDCardInserted()) { // pull card + lSDCardStatus = false; + // Remove SD card when printing + if (card.isStillPrinting()) { // printing + HMI_lcd_flag.remove_card_flag = true; + temp_remove_card_flag = true; + + TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true, false)); // rock_20211016 + + //SERIAL_ECHO_MSG("ROCK_MOVE_CARD2222\n"); + rts.sendData(ExchangePageBase + 47, ExchangepageAddr); + change_page_font = 47; + queue.inject(F("M25")); // M25: Pause the SD print in progress. + } + } + // Refresh SD card status + else + lSDCardStatus = card.isSDCardInserted(); +} + +inline void RTS_line_to_current(AxisEnum axis) { + if (!planner.is_full()) + planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[(int8_t)axis]), active_extruder); +} + +static void RTS_line_to_filelist() { + // clean filename Icon + for (int j = 0; j < 4; j++) + for (int i = 0; i < TEXTBYTELEN; i++) + rts.sendData(0, CardRecbuf.addr[j] + i); + + memset(&CardRecbuf, 0, sizeof(CardRecbuf)); + + int num = 0; + for (uint16_t i = (file_current_page - 1) * 4; i < (file_current_page * 4); i++) { + card.selectFileByIndex(fileCnt - 1 - i); + char *pointFilename = card.longFilename; + int filenamelen = strlen(card.longFilename); + int j = 1; + while ((strncmp(&pointFilename[j], ".gcode", 6) && strncmp(&pointFilename[j], ".GCODE", 6)) && ((j++) < filenamelen)); + + if (j >= TEXTBYTELEN) { + strncpy(&card.longFilename[TEXTBYTELEN - 3], "..", 2); + card.longFilename[TEXTBYTELEN - 1] = '\0'; + j = TEXTBYTELEN - 1; + } + strncpy(CardRecbuf.Cardshowfilename[num], card.longFilename, j); + + strcpy(CardRecbuf.Cardfilename[num], card.filename); + CardRecbuf.addr[num] = FILE1_TEXT_VP + (num * 20); + rts.sendData(CardRecbuf.Cardshowfilename[num], CardRecbuf.addr[num]); + CardRecbuf.Filesum = (++num); + } + page_total_file = CardRecbuf.Filesum; + CardRecbuf.Filesum = ((file_total_page - 1) * 4) + page_total_file; +} + +RTS::RTS() { + recdat.head[0] = snddat.head[0] = FHONE; + recdat.head[1] = snddat.head[1] = FHTWO; + ZERO(databuf); +} + +void RTS::sdCardInit() { + if (sdDetected()) // 如果检测到有卡插入 + card.mount(); + + DEBUG_ECHOLNPGM(" card.flag.mounted=: ", card.flag.mounted); + + if (card.flag.mounted) { // 挂载成功 + fileCnt = card.get_num_items(); + card.getWorkDirName(); + if (card.filename[0] != '/') card.cdup(); + hal.watchdog_refresh(); // 解决拔插卡重启的问题,Rock_20220915 + + if (fileCnt > 4) { + file_total_page = (fileCnt / 4) + 1; + if (file_total_page > 5) file_total_page = 5; // rock_20221412 + } + else + file_total_page = 1; + + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + file_current_page = 1; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + RTS_line_to_filelist(); // rock_20220915 + CardRecbuf.selectFlag = false; + + // rock_20220707 + if (PoweroffContinue /*|| print_job_timer.isRunning()*/) return; + + // clean print file + for (int j = 0; j < 20; j++) sendData(0, PRINT_FILE_TEXT_VP + j); + lcd_sd_status = card.isSDCardInserted(); + } + else { + if (PoweroffContinue) return; + + // Clean filename Icon + for (int j = 0; j < MaxFileNumber; j++) + for (int i = 0; i < TEXTBYTELEN; i++) + sendData(0, CardRecbuf.addr[j] + i); + + memset(&CardRecbuf, 0, sizeof(CardRecbuf)); + } +} + +bool RTS::sdDetected() { + static bool last, state; + static bool flag_stable; + static uint32_t stable_point_time; + + bool tmp = card.isSDCardInserted(); + + if (tmp != last) + flag_stable = false; + else if (!flag_stable) { + flag_stable = true; + stable_point_time = millis() + 30; + } + + if (flag_stable && ELAPSED(millis(), stable_point_time)) + state = tmp; + + last = tmp; + + return state; +} + +void RTS::sdCardUpate() { + const bool sd_status = sdDetected(); + + if (sd_status != lcd_sd_status) { + if (sd_status) { + // SD card power on + sdCardInit(); + } + else { + + if (PoweroffContinue /*|| print_job_timer.isRunning()*/) return; + + card.release(); + for (int i = 0; i < CardRecbuf.Filesum; i++) { + for (int j = 0; j < 20; j++) sendData(0, CardRecbuf.addr[i] + j); + sendData((unsigned long)0xFFFF, FilenameNature + (i + 1) * 16); + } + for (int j = 0; j < 20; j++) { + // clean screen. + sendData(0, PRINT_FILE_TEXT_VP + j); + sendData(0, SELECT_FILE_TEXT_VP + j); + } + memset(&CardRecbuf, 0, sizeof(CardRecbuf)); + sendData(1, PRINT_COUNT_PAGE_DATA_VP); + file_total_page = 1; + sendData(1, PRINT_CURRENT_PAGE_DATA_VP); + file_current_page = 1; + } + lcd_sd_status = sd_status; + } + + // represents to update file list + if (CardUpdate && lcd_sd_status && sdDetected()) { + RTS_line_to_filelist(); + for (uint16_t i = 0; i < 5; i++) { + delay(1); + sendData((unsigned long)0xFFFF, FilenameNature + (i + 1) * 16); + } + hal.watchdog_refresh(); + CardUpdate = false; + } +} + +void RTS::init() { + #if ENABLED(MENU_RESET_WIFI) + SET_OUTPUT(RESET_WIFI_PIN); + OUT_WRITE(RESET_WIFI_PIN, HIGH); + #endif + + #if PIN_EXISTS(LED_CONTROL) + SET_OUTPUT(LED_CONTROL_PIN); + #endif + + #if ENABLED(POWER_LOSS_RECOVERY) + if (!card.isSDCardInserted()) { delay(500); card.mount(); } + if (card.isSDCardInserted()) recovery.check(); + #endif + + delay(500); + + AxisUnitMode = 1; + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + bool zig = true; + int8_t inStart, inStop, inInc, showcount; + showcount = 0; + settings.load(); + st_bedNozzleHeightCal.zCoordinateOffset = bedNozzleHeightCalZ;// caixiaoliang add 20210807 + for (int y = 0; y < GRID_MAX_POINTS_Y; y++) { + // away from origin + if (zig) { + inStart = 0; + inStop = GRID_MAX_POINTS_X; + inInc = 1; + } + else { + // towards origin + inStart = GRID_MAX_POINTS_X - 1; + inStop = -1; + inInc = -1; + } + zig ^= true; + for (int x = inStart; x != inStop; x += inInc) { + sendData(bedlevel.z_values[x][y] * 1000, AUTO_BED_LEVEL_1POINT_VP + showcount * 2); + showcount++; + } + } + + #endif // AUTO_BED_LEVELING_BILINEAR + + last_zoffset = zprobe_zoffset = probe.offset.z; + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + + for (int i = 0; i < 9; i++) sendData(0, LANGUAGE_CHINESE_TITLE_VP + i); + sendData(1, LANGUAGE_CHINESE_TITLE_VP + ui.language); + updateLanguageDisplay(); + delay(500); + + last_target_temperature[0] = thermalManager.degTargetHotend(0); + last_target_temperature_bed = thermalManager.degTargetBed(); + feedrate_percentage = 100; + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + + /***************turn off motor*****************/ + sendData(1, MOTOR_FREE_ICON_VP); + + /***************transmit temperature to screen*****************/ + sendData(0, HEAD_SET_TEMP_VP); + sendData(0, BED_SET_TEMP_VP); + sendData(thermalManager.degHotend(0), HEAD_CURRENT_TEMP_VP); + delay(20); + #if ENABLED(BED_TEMP_COMP) + float bedTempDisp = thermalManager.degBed(); + if (thermalManager.degTargetBed() > 65 && thermalManager.degTargetBed() <= 127) { + if (bedTempDisp > 65 && bedTempDisp <= 86) + bedTempDisp -= (5 * bedTempDisp) / thermalManager.degTargetBed(); + else if (bedTempDisp > 86 && bedTempDisp <= 127) + bedTempDisp -= (7 * bedTempDisp) / thermalManager.degTargetBed(); + } + sendData(bedTempDisp, BED_CURRENT_TEMP_VP); + #else + sendData(thermalManager.degBed(), BED_CURRENT_TEMP_VP); + #endif + + delay(20); + sendData(ui.material_preset[0].hotend_temp, PREHEAT_PLA_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[0].bed_temp, PREHEAT_PLA_SET_BED_TEMP_VP); + sendData(ui.material_preset[1].hotend_temp, PREHEAT_ABS_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[1].bed_temp, PREHEAT_ABS_SET_BED_TEMP_VP); + + sendData(planner.settings.max_feedrate_mm_s[0], MAX_VELOCITY_XAXIS_DATA_VP); + sendData(planner.settings.max_feedrate_mm_s[1], MAX_VELOCITY_YAXIS_DATA_VP); + sendData(planner.settings.max_feedrate_mm_s[2], MAX_VELOCITY_ZAXIS_DATA_VP); + sendData(planner.settings.max_feedrate_mm_s[3], MAX_VELOCITY_EAXIS_DATA_VP); + + sendData(planner.settings.max_acceleration_mm_per_s2[0], MAX_ACCEL_XAXIS_DATA_VP); + sendData(planner.settings.max_acceleration_mm_per_s2[1], MAX_ACCEL_YAXIS_DATA_VP); + sendData(planner.settings.max_acceleration_mm_per_s2[2], MAX_ACCEL_ZAXIS_DATA_VP); + sendData(planner.settings.max_acceleration_mm_per_s2[3], MAX_ACCEL_EAXIS_DATA_VP); + + sendData(planner.max_jerk.x * 100, MAX_JERK_XAXIS_DATA_VP); + sendData(planner.max_jerk.y * 100, MAX_JERK_YAXIS_DATA_VP); + sendData(planner.max_jerk.z * 100, MAX_JERK_ZAXIS_DATA_VP); + sendData(planner.max_jerk.e * 100, MAX_JERK_EAXIS_DATA_VP); + + sendData(planner.settings.axis_steps_per_mm[0] * 10, MAX_STEPSMM_XAXIS_DATA_VP); + sendData(planner.settings.axis_steps_per_mm[1] * 10, MAX_STEPSMM_YAXIS_DATA_VP); + sendData(planner.settings.axis_steps_per_mm[2] * 10, MAX_STEPSMM_ZAXIS_DATA_VP); + sendData(planner.settings.axis_steps_per_mm[3] * 10, MAX_STEPSMM_EAXIS_DATA_VP); + + sendData(thermalManager.temp_hotend[0].pid.p() * 100, NOZZLE_TEMP_P_DATA_VP); + sendData(thermalManager.temp_hotend[0].pid.i() * 100, NOZZLE_TEMP_I_DATA_VP); + sendData(thermalManager.temp_hotend[0].pid.d() * 100, NOZZLE_TEMP_D_DATA_VP); + sendData(thermalManager.temp_bed.pid.p() * 100, HOTBED_TEMP_P_DATA_VP); + sendData(thermalManager.temp_bed.pid.i() * 100, HOTBED_TEMP_I_DATA_VP); + sendData(thermalManager.temp_bed.pid.d() * 10, HOTBED_TEMP_D_DATA_VP); + + /***************transmit Fan speed to screen*****************/ + // turn off fans + thermalManager.set_fan_speed(0, 0); + sendData(1, PRINTER_FANOPEN_TITLE_VP); + sendData(0, PRINTER_LEDOPEN_TITLE_VP); + LEDStatus = false; + delay(5); + + /*********transmit SD card filename to screen***************/ + sdCardInit(); + + /***************transmit Printer information to screen*****************/ + sendData(MACHINE_NAME, MACHINE_NAME_ABOUT_TEXT_VP); + sendData(FIRMWARE_VERSION, FIRMWARE_VERSION_ABOUT_TEXT_VP); + //sendData(SCREEN_VERSION, PRINTER_DISPLAY_VERSION_TEXT_VP); + sendData(HARDWARE_VERSION, HARDWARE_VERSION_ABOUT_TEXT_VP); + sendData(PRINT_SIZE, PRINTER_PRINTSIZE_TEXT_VP); + delay(5); + sendData(ui.language == 0 ? CORP_WEBSITE_C : CORP_WEBSITE_E, WEBSITE_ABOUT_TEXT_VP); + + RTS_UpdateWifi(); + + sendData(recovery.enabled ? 0 : 1, POWERCONTINUE_CONTROL_ICON_VP); + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + sendData(runout.enabled ? 0 : 1, FILAMENT_CONTROL_ICON_VP); + #endif + + /**************************some info init*******************************/ + sendData(0, PRINT_PROCESS_ICON_VP); + sendData(1, PREHAEAT_NOZZLE_ICON_VP); + sendData(1, PREHAEAT_HOTBED_ICON_VP); + + sendData(ExchangePageBase, ExchangepageAddr); + change_page_font = 0; + + for (startprogress = 0; startprogress <= 80; startprogress++) { + sendData(startprogress, START_PROCESS_ICON_VP); + delay(100); + hal.watchdog_refresh(); + } + delay(200); + hal.watchdog_refresh(); + + update_time_value = RTS_UPDATE_VALUE; +} + +int RTS::receiveData() { + static int recnum = 0; + #define DWINBUF_MAX 256 + static bool recvflag = false; + static uint8_t databuf[DWINBUF_MAX]; + + // Parse data frame + if (LCD_SERIAL.available() > 0 && recnum < (signed)sizeof(databuf)) { + databuf[recnum++] = LCD_SERIAL.read(); + + //#define RECV_DEBUG + #ifdef RECV_DEBUG + char buf[16]; + sprintf_P(buf, PSTR("%02x "), databuf[recnum - 1]); + serial_print_P(buf); + #endif + + // Verify the frame head + if ((recnum == 1) && (databuf[0] != 0x5A)) { + recnum = 0; + } + else if ((recnum == 2) && (databuf[1] != 0xA5)) { + // Verify the frame head + recnum = 0; + } + else if ((recnum == 4) && (databuf[3] != 0x83)) { + // Parse only the read command 0x83 and filter out the reply command 0x82 + recnum = 0; + } + else if ((recnum >= 3) && (databuf[2] == (recnum - 3))) { + // Complete resolution + recvflag = true; + + #ifdef RECV_DEBUG + serial_print_P("\n"); + SERIAL_ECHO_MSG("dwin rx ok"); + #endif + } + else if ((recnum >= 3) && ((recnum - 3) > databuf[2])) { + // The actual received data bytes were larger than the frame data bytes, parsing failed + recnum = 0; + } + } + + if (!recvflag) return -1; + + recvflag = false; + + // receive nothing + if (recnum < 1) return -1; + + if (recdat.head[0] == databuf[0] && recdat.head[1] == databuf[1] && recnum > 2) { + recdat.len = databuf[2]; + recdat.command = databuf[3]; + // response for writing byte + if ((recdat.len == 0x03) && ((recdat.command == 0x82) || (recdat.command == 0x80)) && (databuf[4] == 0x4F) && (databuf[5] == 0x4B)) { + ZERO(databuf); + recnum = 0; + return -1; + } + else if (recdat.command == 0x83) { + // response for reading the data from the variate + recdat.addr = databuf[4]; + recdat.addr = (recdat.addr << 8) | databuf[5]; + recdat.bytelen = databuf[6]; + for (unsigned int i = 0; i < recdat.bytelen; i += 2) { + recdat.data[i / 2] = databuf[7 + i]; + recdat.data[i / 2] = (recdat.data[i / 2] << 8) | databuf[8 + i]; + } + } + else if (recdat.command == 0x81) { + // response for reading the page from the register + recdat.addr = databuf[4]; + recdat.bytelen = databuf[5]; + for (unsigned int i = 0; i < recdat.bytelen; i++) { + recdat.data[i] = databuf[6 + i]; + //recdat.data[i] = (recdat.data[i] << 8 )| databuf[7 + i]; + } + } + } + else { + ZERO(databuf); + recnum = 0; + // receive the wrong data + return -1; + } + ZERO(databuf); + recnum = 0; + return 2; +} + +void RTS::sendData() { + if (snddat.head[0] == FHONE && snddat.head[1] == FHTWO && snddat.len >= 3) { + databuf[0] = snddat.head[0]; + databuf[1] = snddat.head[1]; + databuf[2] = snddat.len; + databuf[3] = snddat.command; + + // to write data to the register + if (snddat.command == 0x80) { + databuf[4] = snddat.addr; + for (int i = 0; i < (snddat.len - 2); i++) databuf[5 + i] = snddat.data[i]; + } + else if ((snddat.len == 3) && (snddat.command == 0x81)) { + // to read data from the register + databuf[4] = snddat.addr; + databuf[5] = snddat.bytelen; + } + else if (snddat.command == 0x82) { + // to write data to the variate + databuf[4] = snddat.addr >> 8; + databuf[5] = snddat.addr & 0xFF; + for (int i = 0; i < (snddat.len - 3); i += 2) { + databuf[6 + i] = snddat.data[i / 2] >> 8; + databuf[7 + i] = snddat.data[i / 2] & 0xFF; + } + } + else if (snddat.len == 4 && snddat.command == 0x83) { + // to read data from the variate + databuf[4] = snddat.addr >> 8; + databuf[5] = snddat.addr & 0xFF; + databuf[6] = snddat.bytelen; + } + //usart_tx(LCD_SERIAL.c_dev(), databuf, snddat.len + 3); + //LCD_SERIAL.flush(); + for (int i = 0; i < (snddat.len + 3); i++) { + LCD_SERIAL.write(databuf[i]); + delayMicroseconds(1); + } + + memset(&snddat, 0, sizeof(snddat)); + ZERO(databuf); + snddat.head[0] = FHONE; + snddat.head[1] = FHTWO; + } +} + +//void RTS::sendData(const String &s, unsigned long addr, unsigned char cmd/*=VarAddr_W*/) { +// if (s.length() < 1) return; +// sendData(s.c_str(), addr, cmd); +//} + +void RTS::sendData(const char *str, unsigned long addr, unsigned char cmd/*=VarAddr_W*/) { + int len = strlen(str); + if (len > 0) { + databuf[0] = FHONE; + databuf[1] = FHTWO; + databuf[2] = 3 + len; + databuf[3] = cmd; + databuf[4] = addr >> 8; + databuf[5] = addr & 0x00FF; + for (int i = 0; i < len; i++) databuf[6 + i] = str[i]; + + for (int i = 0; i < (len + 6); i++) { + LCD_SERIAL.write(databuf[i]); + delayMicroseconds(1); + } + ZERO(databuf); + } +} + +void RTS::sendData(char c, unsigned long addr, unsigned char cmd/*=VarAddr_W*/) { + snddat.command = cmd; + snddat.addr = addr; + snddat.data[0] = (unsigned long)c; + snddat.data[0] = snddat.data[0] << 8; + snddat.len = 5; + sendData(); +} + +void RTS::sendData(unsigned char *str, unsigned long addr, unsigned char cmd) { sendData((char *)str, addr, cmd); } + +void RTS::sendData(int n, unsigned long addr, unsigned char cmd/*=VarAddr_W*/) { + if (cmd == VarAddr_W) { + if (n > 0xFFFF) { + snddat.data[0] = n >> 16; + snddat.data[1] = n & 0xFFFF; + snddat.len = 7; + } + else { + snddat.data[0] = n; + snddat.len = 5; + } + } + else if (cmd == RegAddr_W) { + snddat.data[0] = n; + snddat.len = 3; + } + else if (cmd == VarAddr_R) { + snddat.bytelen = n; + snddat.len = 4; + } + snddat.command = cmd; + snddat.addr = addr; + sendData(); +} + +void RTS::sendData(unsigned int n, unsigned long addr, unsigned char cmd) { sendData((int)n, addr, cmd); } + +void RTS::sendData(float n, unsigned long addr, unsigned char cmd) { sendData((int)n, addr, cmd); } + +void RTS::sendData(long n, unsigned long addr, unsigned char cmd) { sendData((unsigned long)n, addr, cmd); } + +void RTS::sendData(unsigned long n, unsigned long addr, unsigned char cmd/*=VarAddr_W*/) { + if (cmd == VarAddr_W) { + if (n > 0xFFFF) { + snddat.data[0] = n >> 16; + snddat.data[1] = n & 0xFFFF; + snddat.len = 7; + } + else { + snddat.data[0] = n; + snddat.len = 5; + } + } + else if (cmd == VarAddr_R) { + snddat.bytelen = n; + snddat.len = 4; + } + snddat.command = cmd; + snddat.addr = addr; + sendData(); +} + +void RTS::sendText(const char string[], unsigned long addr, uint8_t textSize) { + for (int8_t i = 0; i < textSize; i++) sendData(0, addr + i); + sendData(string, addr); +} + +void RTS::sdCardStop() { + if (PoweroffContinue) { + planner.synchronize(); + //card.endFilePrint(); + card.abortFilePrintSoon(); + queue.clear(); + quickstop_stepper(); + print_job_timer.stop(); + IF_DISABLED(SD_ABORT_NO_COOLDOWN, thermalManager.disable_all_heaters()); + print_job_timer.reset(); + marlin.end_waiting(); + PoweroffContinue = false; + sd_printing_autopause = false; + TERN_(POWER_LOSS_RECOVERY, if (card.flag.mounted) card.removeJobRecoveryFile()); + CardRecbuf.recordcount = -1; + } + SERIAL_ECHOLNPGM("M79 S4"); // 4:cloud print stop + + // Shut down the stepper motor. + //queue.enqueue_now(F("M84")); + sendData(1, MOTOR_FREE_ICON_VP); + + sendData(0, PRINT_PROCESS_ICON_VP); + sendData(0, PRINT_PROCESS_VP); + delay(2); + for (int j = 0; j < 20; j++) { + // clean screen. + sendData(0, PRINT_FILE_TEXT_VP + j); + // clean filename + sendData(0, SELECT_FILE_TEXT_VP + j); + } + //waitway = 0; + //sendData(ExchangePageBase + 1, ExchangepageAddr); + //change_page_font = 1; +} + +void RTS::handleData() { + proc_command_t Checkkey = NoKey; + // for waiting + if (waitway > 0) { + memset(&recdat, 0, sizeof(recdat)); + recdat.head[0] = FHONE; + recdat.head[1] = FHTWO; + return; + } + for (int i = 0; Addrbuf[i] != 0; i++) + if (recdat.addr == Addrbuf[i]) { + Checkkey = proc_command_t(i); + break; + } + + if (Checkkey < 0) { + memset(&recdat, 0, sizeof(recdat)); + recdat.head[0] = FHONE; + recdat.head[1] = FHTWO; + return; + } + + switch (Checkkey) { + case MainEnterKey: + + if (recdat.data[0] == 1) { + CardUpdate = true; + CardRecbuf.recordcount = -1; + if (true == g_heaterLoadTempAdd) break; + for (int j = 0; j < 20; j++) { + // clean screen. + sendData(0, PRINT_FILE_TEXT_VP + j); + // clean filename + sendData(0, SELECT_FILE_TEXT_VP + j); + } + for (int j = 0; j < 20; j++) sendData(0, FILE1_SELECT_ICON_VP + j); + sdCardUpate(); + + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + file_current_page = 1; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + + sendData(ExchangePageBase + 2, ExchangepageAddr); + change_page_font = 2; + if (card.isSDCardInserted()) RTS_line_to_filelist(); + } + else if (recdat.data[0] == 2) { + AxisUnitMode = 3; + axis_unit = 0.1; + RTS_UpdatePosition(); + sendData(ExchangePageBase + 16, ExchangepageAddr); + change_page_font = 16; + } + else if (recdat.data[0] == 3) { + if (true == g_heaterLoadTempAdd) break; + sendData(ExchangePageBase + 21, ExchangepageAddr); + change_page_font = 21; + } + else if (recdat.data[0] == 4) { + leveling_flag = true; // Enter the leveling page + //gcode.process_subcommands_now(F("M420 S0")); // Enter the leveling page and turn off the automatic compensation first + sendData(ExchangePageBase + 25, ExchangepageAddr); + change_page_font = 25; + gcode.process_subcommands_now(F("G28")); + gcode.process_subcommands_now(F("M420 S0")); // Enter the leveling page and turn off the automatic compensation first + gcode.process_subcommands_now(F("G1 X110 Y110 F3000")); + gcode.process_subcommands_now(F("G1 F600 Z0")); + } + else if (recdat.data[0] == 5) { + queue.clear(); + quickstop_stepper(); + print_job_timer.stop(); + sendData(1, MOTOR_FREE_ICON_VP); + sendData(0, PRINT_PROCESS_ICON_VP); + sendData(0, PRINT_PROCESS_VP); + + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + print_job_timer.reset(); + sd_printing_autopause = false; + for (int j = 0; j < 20; j++) { + // clean screen. + sendData(0, PRINT_FILE_TEXT_VP + j); + // clean filename + sendData(0, SELECT_FILE_TEXT_VP + j); + } + CardRecbuf.recordcount = -1; //不选中 + sendData(ExchangePageBase + 1, ExchangepageAddr);// rock_20220708 + change_page_font = 1; + } + else if (recdat.data[0] == 6) { + #if ENABLED(BLTOUCH) + waitway = 3; + sendData(ui.language + 1, BEDLEVELING_WAIT_TITLE_VP); + sendData(ExchangePageBase + 26, ExchangepageAddr); + change_page_font = 26; + + //RTS_ProbingPauseHotend(); + //RTS_ProbingPauseFans(); + + queue.enqueue_now(F("G28\nG29")); + sendData(0, MOTOR_FREE_ICON_VP); + #endif + } + else if (recdat.data[0] == 7) { + if (errorway == 1) { + } + else if (errorway == 2) { + // auto home fail + } + else if (errorway == 3) { + // bed leveling fail + } + else if (errorway == 4) { + } + } + else if (recdat.data[0] == 8) { + if (true == g_heaterLoadTempAdd) break; + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + break; + + case AdjustEnterKey: + if (recdat.data[0] == 1) { + sendData(thermalManager.fan_speed[0] ? 0 : 1, PRINTER_FANOPEN_TITLE_VP); + sendData(ExchangePageBase + 14, ExchangepageAddr); + change_page_font = 14; + } + else if (recdat.data[0] == 2) { + if (PoweroffContinue) { + if (card.isPrinting() || marlin.wait_for_heatup) { + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + } + else { + sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + } + else { + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + } + settings.save(); + } + else if (recdat.data[0] == 3) { + const bool fanOn = thermalManager.fan_speed[0]; + sendData(fanOn ? 1 : 0, PRINTER_FANOPEN_TITLE_VP); + thermalManager.set_fan_speed(0, fanOn ? 0 : 255); + } + else if (recdat.data[0] == 4) { + if (LEDStatus) { + sendData(0, PRINTER_LEDOPEN_TITLE_VP); + //WRITE(LED_CONTROL_PIN, HIGH); + LEDStatus = false; + } + else { + sendData(1, PRINTER_LEDOPEN_TITLE_VP); + //WRITE(LED_CONTROL_PIN, LOW); + LEDStatus = true; + } + } + else if (recdat.data[0] == 5) { + sendData(ExchangePageBase + 15, ExchangepageAddr); + change_page_font = 15; + } + else if (recdat.data[0] == 6) { + } + else if (recdat.data[0] == 7) { + sendData(ExchangePageBase + 14, ExchangepageAddr); + change_page_font = 14; + settings.save(); + } + else if (recdat.data[0] == 8) { + if (runout.enabled) { + sendData(1, FILAMENT_CONTROL_ICON_VP); + runout.enabled = false; + } + else { + sendData(0, FILAMENT_CONTROL_ICON_VP); + runout.enabled = true; + } + } + else if (recdat.data[0] == 9) { + if (recovery.enabled) { + sendData(1, POWERCONTINUE_CONTROL_ICON_VP); + recovery.enabled = false; + if (card.flag.mounted) { // rock_20220701 Fix the bug that the switch is always on when the power is off + #if ENABLED(POWER_LOSS_RECOVERY) + //card.removeJobRecoveryFile(); + if (card.jobRecoverFileExists()) + //recovery.init(); // Do not clear power-off information + card.removeFile(recovery.filename); + #endif + } + } + else { + sendData(0, POWERCONTINUE_CONTROL_ICON_VP); + recovery.enabled = true; + recovery.save(true); + } + } + else if (recdat.data[0] == 10) { + sendData(ExchangePageBase + 32, ExchangepageAddr); + change_page_font = 32; + settings.save(); + } + break; + + case PrintSpeedEnterKey: + feedrate_percentage = recdat.data[0]; + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + SERIAL_ECHOLNPGM("M220 S", feedrate_percentage); + break; + + case StopPrintKey: + if (recdat.data[0] == 1) { // Stop printing pop-up window entry + if (HMI_lcd_flag.home_flag) break; + sendData(ExchangePageBase + 13, ExchangepageAddr); + change_page_font = 13; + } + else if (recdat.data[0] == 2) { // Stop printing popup confirmation + if (!PoweroffContinue) { // rock_20220708 Cloud printing + SERIAL_ECHOLNPGM("ok"); + while ((planner.movesplanned() < 2) && (destination != current_position)) marlin.idle(); + queue.clear(); + delay(20); + + thermalManager.setTargetHotend(0, 0); + sendData(0, HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(0); + sendData(0, BED_SET_TEMP_VP); + SERIAL_ECHOLNPGM("M79 S4"); + queue.enqueue_now(F("M79 S4")); // 4:cloud print stop + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + + if (G29_flag || HMI_lcd_flag.home_flag) break; + + if (PoweroffContinue) { + sendData(ExchangePageBase + 40, ExchangepageAddr); + change_page_font = 40; + waitway = 7; + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + thermalManager.setTargetHotend(0, 0); + sendData(0, HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(0); + sendData(0, BED_SET_TEMP_VP); + temphot = 0; + thermalManager.zero_fan_speeds(); + update_time_value = 0; + sdCardStop(); + SERIAL_ECHOLNPGM("M79 S4"); + SERIAL_ECHOLNPGM("ok"); + queue.clear(); + queue.enqueue_now(F("G28 XY\nM84")); + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + } + + } + else if (recdat.data[0] == 3) { // Stop printing the popup and return + if (card.isPrinting() || marlin.wait_for_heatup || HMI_lcd_flag.home_flag) { // 暂停 + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + } + else { // continue to print + sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + } + else if (recdat.data[0] == 4) { + if (!planner.has_blocks_queued()) { // rock_20220401 + if (PoweroffContinue) { + + SERIAL_ECHOLNPGM("ok"); + + runout.filament_ran_out = false; + sendData(ExchangePageBase + 40, ExchangepageAddr); + change_page_font = 40; + waitway = 7; + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled) { + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + ui.pause_show_message(PAUSE_MESSAGE_RESUME); + queue.inject(F("M108")); + } + #endif + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + temphot = 0; + card.abortFilePrintSoon(); + queue.clear(); + quickstop_stepper(); + + print_job_timer.abort(); + // delay(10); + while (planner.has_blocks_queued()) marlin.idle(); + thermalManager.setTargetHotend(0, 0); + thermalManager.setTargetBed(0); + thermalManager.zero_fan_speeds(); + //while (thermalManager.degTargetHotend(0) > 0) { + // thermalManager.setTargetHotend(0, 0); + // marlin.idle(); + //} + sdCardStop(); + + SERIAL_ECHOLNPGM("M79 S4"); // 4:cloud print stop + //sendData(ExchangePageBase + 1, ExchangepageAddr); + // change_page_font = 1; + } + else if (!PoweroffContinue) { + SERIAL_ECHOLNPGM("ok"); + PoweroffContinue = true; + runout.filament_ran_out = false; + sendData(ExchangePageBase + 40, ExchangepageAddr); + change_page_font = 40; + waitway = 7; + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled) { + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + ui.pause_show_message(PAUSE_MESSAGE_RESUME); + queue.inject(F("M108")); + } + #endif + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + temphot = 0; + card.abortFilePrintSoon(); + queue.clear(); + quickstop_stepper(); + + print_job_timer.abort(); + // delay(10); + + while (planner.has_blocks_queued()) marlin.idle(); + + thermalManager.setTargetHotend(0, 0); + thermalManager.setTargetBed(0); + thermalManager.zero_fan_speeds(); + //while (thermalManager.degTargetHotend(0) > 0) { + // thermalManager.setTargetHotend(0, 0); + // marlin.idle(); + //} + sdCardStop(); + + PoweroffContinue = false; + SERIAL_ECHOLNPGM("M79 S4"); // 4:cloud print stop + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + } + } + else if (recdat.data[0] == 5) { // 拔卡打印弹窗停止打印 + if (PoweroffContinue) { + sendData(ExchangePageBase + 40, ExchangepageAddr); + change_page_font = 40; + waitway = 7; + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + thermalManager.setTargetHotend(0, 0); + sendData(0, HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(0); + sendData(0, BED_SET_TEMP_VP); + temphot = 0; + thermalManager.zero_fan_speeds(); + update_time_value = 0; + sdCardStop(); + } + } + break; + + case PausePrintKey: + if (recdat.data[0] == 1) { + // 云打印功能 + if (!PoweroffContinue) { + sendData(ExchangePageBase + 11, ExchangepageAddr); + change_page_font = 11; + } + // rock_20220714 解决打印开始前反复点击暂停会重启的问题 + if (G29_flag || HMI_lcd_flag.home_flag || marlin.wait_for_heatup) break; + sendData(ExchangePageBase + 11, ExchangepageAddr); + change_page_font = 11; + } + else if (recdat.data[0] == 2) { + if (!PoweroffContinue) { + sendData(ExchangePageBase + 40, ExchangepageAddr); + SERIAL_ECHOLNPGM("M79 S2"); // 3:cloud print resume + queue.enqueue_now(F("M79 S2")); // 2:cloud print pause + update_time_value = 0; + print_job_timer.pause(); + sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + + if (G29_flag || HMI_lcd_flag.home_flag || marlin.wait_for_heatup) break; + + if (PoweroffContinue && !marlin.wait_for_heatup && card.isPrinting()) { + while (thermalManager.still_heating(0)) marlin.idle(); + sendData(ExchangePageBase + 40, ExchangepageAddr); + waitway = 1; + pause_e = current_position.e - 3; + if (!temphot) temphot = thermalManager.degTargetHotend(0); + card.pauseSDPrint(); + print_job_timer.pause(); + + pause_action_flag = true; + update_time_value = 0; + planner.synchronize(); + sdcard_pause_check = false; + } + } + else if (recdat.data[0] == 3) { + if (card.isPrinting() || marlin.wait_for_heatup) { + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + } + else { + sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + } + break; + + case ResumePrintKey: + if (recdat.data[0] == 1) { + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + break; + } + #endif + + if (PoweroffContinue) { + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + + #if ENABLED(HAS_RESUME_CONTINUE) + const bool was_wait = marlin.wait_for_user; + marlin.wait_for_user = false; + #else + constexpr bool was_wait = false; + #endif + + if (!was_wait) { + memset(commandbuf, 0, sizeof(commandbuf)); + sprintf_P(commandbuf, PSTR("M109 S%i"), temphot); + queue.enqueue_one_now(commandbuf); + + card.startOrResumeFilePrinting(); + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + } + SERIAL_ECHOLNPGM("M79 S3"); // 3:cloud print resume + } + else { + SERIAL_ECHOLNPGM("M79 S3"); // 3:cloud print resume + //sendData(ExchangePageBase + 40, ExchangepageAddr); + queue.enqueue_now(F("M79 S3")); // 3:cloud print resume + } + } + else if (recdat.data[0] == 2) { + SERIAL_ECHOLNPGM("ok"); + if (G29_flag || HMI_lcd_flag.home_flag) break; + + if (sdcard_pause_check) { + if (thermalManager.degTargetHotend(0) >= EXTRUDE_MINTEMP) { + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + } + else if (temphot >= EXTRUDE_MINTEMP) + thermalManager.setTargetHotend(temphot, 0); + else + thermalManager.setTargetHotend(200, 0); + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + break; + } + else { + if (!planner.has_blocks_queued()) { + sendData(ExchangePageBase + 8, ExchangepageAddr); + change_page_font = 8; + } + else { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + break; + } + } + #endif + } + else if (!sdcard_pause_check) { + if (card.flag.mounted) { + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + break; + } + else { + PoweroffContinue = true; + char cmd[30]; + char *c; + sprintf_P(cmd, PSTR("M23 %s"), CardRecbuf.Cardfilename[CardRecbuf.recordcount]); + for (c = &cmd[4]; *c; c++) *c = tolower(*c); + + ZERO(cmdbuf); + strcpy(cmdbuf, cmd); + queue.enqueue_one_now(cmd); + queue.enqueue_now(F("M24")); + + // clean screen. + for (int j = 0; j < 20; j++) sendData(0, PRINT_FILE_TEXT_VP + j); + + sendData(CardRecbuf.Cardshowfilename[CardRecbuf.recordcount], PRINT_FILE_TEXT_VP); + + delay(2); + + TERN_(BABYSTEPPING, sendData(0, AUTO_BED_LEVEL_ZOFFSET_VP)); + + feedrate_percentage = 100; + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + sendData(ExchangePageBase + 10, ExchangepageAddr); + update_time_value = 0; + // 1:cloud print satrt + SERIAL_ECHOLNPGM("M79 S1"); + } + } + else + break; + } + } + else if (recdat.data[0] == 3) { + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + break; + } + #endif + if (PoweroffContinue) { + runout.filament_ran_out = false; + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + SERIAL_ECHOLNPGM("M79 S1"); + SERIAL_ECHOLNPGM("M79 S3"); + if (temphot > 0) { + sendData(temphot, HEAD_SET_TEMP_VP); + thermalManager.setTargetHotend(temphot, 0); + if (temphot > thermalManager.degHotend(0) - 5) thermalManager.wait_for_hotend(false); + while (thermalManager.still_heating(0)) { + marlin.idle(); + if (card.flag.abort_sd_printing) break; // rock_20220913 + } + } + // Move XY to starting position, then Z + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); + + // Move Z_AXIS to saved position + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + ui.pause_show_message(PAUSE_MESSAGE_RESUME); + queue.inject(F("M108")); + + card.startOrResumeFilePrinting(); + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + } + else if (!PoweroffContinue) { + if (CardRecbuf.recordcount > 0) { + char cmd[30]; + char *c; + sprintf_P(cmd, PSTR("M23 %s"), CardRecbuf.Cardfilename[CardRecbuf.recordcount]); + for (c = &cmd[4]; *c; c++) *c = tolower(*c); + + PoweroffContinue = true; + ZERO(cmdbuf); + strcpy(cmdbuf, cmd); + queue.enqueue_one_now(cmd); + delay(20); + queue.enqueue_now(F("M24")); + // clean screen. + for (int j = 0; j < 20; j++) sendData(0, PRINT_FILE_TEXT_VP + j); + + sendData(CardRecbuf.Cardshowfilename[CardRecbuf.recordcount], PRINT_FILE_TEXT_VP); + + delay(2); + + TERN_(BABYSTEPPING, sendData(0, AUTO_BED_LEVEL_ZOFFSET_VP)); + feedrate_percentage = 100; + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + sendData(ExchangePageBase + 10, ExchangepageAddr); + update_time_value = 0; + // 1:cloud print satrt + SERIAL_ECHOLNPGM("M79 S1"); + SERIAL_ECHOLNPGM("M79 S3"); + } + else { + runout.filament_ran_out = false; + // Move XY to starting position, then Z + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); + + // Move Z_AXIS to saved position + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + ui.pause_show_message(PAUSE_MESSAGE_RESUME); + //queue.inject(F("M108")); + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + + //card.startOrResumeFilePrinting(); + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + SERIAL_ECHOLNPGM("ok"); + if (temphot > 0) { + sendData(temphot, HEAD_SET_TEMP_VP); + thermalManager.setTargetHotend(temphot, 0); + if (temphot > thermalManager.degHotend(0) - 5) thermalManager.wait_for_hotend(false); + while (thermalManager.still_heating(0)) marlin.idle(); + } + SERIAL_ECHOLNPGM("M79 S3"); + } + } + else { + runout.filament_ran_out = false; + // Move XY to starting position, then Z + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); + + // Move Z_AXIS to saved position + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; + ui.pause_show_message(PAUSE_MESSAGE_RESUME); + + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + } + } + else if (recdat.data[0] == 4) { + //if (card.flag.mounted) + if (card.isSDCardInserted()) { //有卡 + SD_Card_status = true; + card.startOrResumeFilePrinting(); + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + sd_printing_autopause = false; + HMI_lcd_flag.remove_card_flag = false; + temp_remove_card_flag = false; + + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + gcode.process_subcommands_now(F("M24")); + } + else { + CardUpdate = true; + sdCardUpate(); + //card.mount(); + //SERIAL_ECHO_MSG("ROCK_MOVE_CARD1111\n"); + sendData(ExchangePageBase + 47, ExchangepageAddr); + change_page_font = 47; + } + } + break; + + case ZoffsetEnterKey: + last_zoffset = zprobe_zoffset; + if (recdat.data[0] >= 32768) { + zprobe_zoffset = (float(recdat.data[0]) - 65536) / 100; + zprobe_zoffset -= 0.001; + } + else { + zprobe_zoffset = float(recdat.data[0]) / 100; + zprobe_zoffset += 0.001; + } + if (WITHIN((zprobe_zoffset), PROBE_OFFSET_ZMIN, PROBE_OFFSET_ZMAX)) { + babystep.add_mm(Z_AXIS, zprobe_zoffset - last_zoffset); + SERIAL_ECHO_MSG("babystep.add_mm():", zprobe_zoffset - last_zoffset); + } + hal.watchdog_refresh(); + probe.offset.z = zprobe_zoffset; + //settings.save(); + break; + + case TempControlKey: + if (recdat.data[0] == 2) { + sendData(ExchangePageBase + 20, ExchangepageAddr); + change_page_font = 20; + } + else if (recdat.data[0] == 3) { + sendData(ui.material_preset[0].hotend_temp, PREHEAT_PLA_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[0].bed_temp, PREHEAT_PLA_SET_BED_TEMP_VP); + delay(2); + sendData(ExchangePageBase + 22, ExchangepageAddr); + change_page_font = 22; + } + else if (recdat.data[0] == 4) { + sendData(ui.material_preset[1].hotend_temp, PREHEAT_ABS_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[1].bed_temp, PREHEAT_ABS_SET_BED_TEMP_VP); + delay(2); + sendData(ExchangePageBase + 23, ExchangepageAddr); + change_page_font = 23; + } + else if (recdat.data[0] == 5) { + thermalManager.setTargetHotend(ui.material_preset[0].hotend_temp, 0); + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(ui.material_preset[0].bed_temp); + //thermalManager.setTargetBed(thermalManager.degTargetBed()); + #if ENABLED(BED_TEMP_COMP) + if (WITHIN(thermalManager.degTargetBed(), 66, 85)) + sendData(thermalManager.degTargetBed() - 5, BED_SET_TEMP_VP); + else if (WITHIN(thermalManager.degTargetBed(), 86, 127)) + sendData(thermalManager.degTargetBed() - 7, BED_SET_TEMP_VP); + #else + sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + #endif + //sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + } + else if (recdat.data[0] == 6) { + thermalManager.setTargetHotend(ui.material_preset[1].hotend_temp, 0); + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(ui.material_preset[1].bed_temp); + //thermalManager.setTargetBed(thermalManager.degTargetBed()); + #if ENABLED(BED_TEMP_COMP) + if (WITHIN(thermalManager.degTargetBed(), 66, 85)) + sendData(thermalManager.degTargetBed() - 5, BED_SET_TEMP_VP); + else if (WITHIN(thermalManager.degTargetBed(), 86, 127)) + sendData(thermalManager.degTargetBed() - 7, BED_SET_TEMP_VP); + #else + sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + #endif + } + else if (recdat.data[0] == 7) { + sendData(ExchangePageBase + 21, ExchangepageAddr); + change_page_font = 21; + } + else if (recdat.data[0] == 8) { + if (true == g_heaterLoadTempAdd) break; + sendData(ExchangePageBase + 20, ExchangepageAddr); + change_page_font = 20; + } + break; + + case CoolDownKey: + if (recdat.data[0] == 1) { + thermalManager.setTargetHotend(0, 0); + sendData(0, HEAD_SET_TEMP_VP); + thermalManager.setTargetBed(0); + sendData(0, BED_SET_TEMP_VP); + thermalManager.fan_speed[0] = 255; + sendData(0, PRINTER_FANOPEN_TITLE_VP); + } + else if (recdat.data[0] == 2) { + sendData(ExchangePageBase + 21, ExchangepageAddr); + change_page_font = 21; + } + break; + + case HeaterTempEnterKey: // rock_20220624 + temphot = recdat.data[0]; + thermalManager.setTargetHotend(temphot, 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + break; + + case HotBedTempEnterKey: + tempbed = recdat.data[0]; + temp_bed_display = recdat.data[0]; + #if ENABLED(BED_TEMP_COMP) + if (WITHIN(tempbed, 61, 80)) + tempbed += 5; + else if (WITHIN(tempbed, 81, 120)) + tempbed += 7; + #endif + thermalManager.setTargetBed(tempbed); + sendData(temp_bed_display, BED_SET_TEMP_VP); + break; + + //case HeaterTempEnterKey: + // temphot = recdat.data[0]; + // thermalManager.setTargetHotend(temphot, 0); + // //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + // sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + // break; + + //case HotBedTempEnterKey: + // thermalManager.setTargetBed(recdat.data[0]); + // //thermalManager.setTargetBed(thermalManager.degTargetBed()); + // sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + // break; + + case PrepareEnterKey: + if (recdat.data[0] == 1) { + sendData(ExchangePageBase + 28, ExchangepageAddr); + change_page_font = 28; + } + else if (recdat.data[0] == 2) { + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + } + else if (recdat.data[0] == 3) { + if (true == g_heaterLoadTempAdd) break; + RTS_UpdatePosition(); + delay(2); + sendData(ExchangePageBase + 16, ExchangepageAddr); + change_page_font = 16; + } + else if (recdat.data[0] == 4) { + // OUT_WRITE(SHUTIDOWN_PIN, LOW); + delay(2000); + } + else if (recdat.data[0] == 5) { + sendData(MACHINE_NAME, MACHINE_NAME_ABOUT_TEXT_VP); + sendData(FIRMWARE_VERSION, FIRMWARE_VERSION_ABOUT_TEXT_VP); + //sendData(SCREEN_VERSION, PRINTER_DISPLAY_VERSION_TEXT_VP); + sendData(HARDWARE_VERSION, HARDWARE_VERSION_ABOUT_TEXT_VP); + sendData(PRINT_SIZE, PRINTER_PRINTSIZE_TEXT_VP); + delay(5); + sendData(ui.language == 0 ? CORP_WEBSITE_C : CORP_WEBSITE_E, WEBSITE_ABOUT_TEXT_VP); + sendData(ExchangePageBase + 24, ExchangepageAddr); + change_page_font = 24; + } + else if (recdat.data[0] == 6) { + queue.enqueue_now(F("M84")); + sendData(1, MOTOR_FREE_ICON_VP); + g_uiXYAxisEnable = false; + g_uiZAxisEnable = false; + } + else if (recdat.data[0] == 7) { + sendData(ExchangePageBase + 43, ExchangepageAddr); + change_page_font = 43; + } + else if (recdat.data[0] == 8) { + settings.save(); + sendData(ExchangePageBase + 21, ExchangepageAddr); + change_page_font = 21; + } + else if (recdat.data[0] == 9) { + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + else if (recdat.data[0] == 10) { + sendData(ExchangePageBase + 42, ExchangepageAddr); + change_page_font = 42; + } + else if (recdat.data[0] == 11) { + #if ENABLED(MENU_RESET_WIFI) + rts_wifi_state = PRESSED; + OUT_WRITE(RESET_WIFI_PIN, LOW); + #endif + flag_counter_wifi_reset = true; + sendData(ExchangePageBase + 45, ExchangepageAddr); + change_page_font = 45; + } + else if (recdat.data[0] == 12) { + sendData(ExchangePageBase + 44, ExchangepageAddr); + change_page_font = 44; + } + else if (recdat.data[0] == 13) { + settings.reset(); + settings.save(); + updateLanguageDisplay(); + for (int i = 0; i < 9; i++) sendData(0, LANGUAGE_CHINESE_TITLE_VP + i); + sendData(1, LANGUAGE_CHINESE_TITLE_VP + ui.language); + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + + sendData(ui.material_preset[0].hotend_temp, PREHEAT_PLA_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[0].bed_temp, PREHEAT_PLA_SET_BED_TEMP_VP); + sendData(ui.material_preset[1].hotend_temp, PREHEAT_ABS_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[1].bed_temp, PREHEAT_ABS_SET_BED_TEMP_VP); + delay(20); + + sendData(default_max_feedrate[X_AXIS], MAX_VELOCITY_XAXIS_DATA_VP); + sendData(default_max_feedrate[Y_AXIS], MAX_VELOCITY_YAXIS_DATA_VP); + sendData(default_max_feedrate[Z_AXIS], MAX_VELOCITY_ZAXIS_DATA_VP); + sendData(default_max_feedrate[E_AXIS], MAX_VELOCITY_EAXIS_DATA_VP); + delay(20); + + sendData(default_max_acceleration[X_AXIS], MAX_ACCEL_XAXIS_DATA_VP); + sendData(default_max_acceleration[Y_AXIS], MAX_ACCEL_YAXIS_DATA_VP); + sendData(default_max_acceleration[Z_AXIS], MAX_ACCEL_ZAXIS_DATA_VP); + sendData(default_max_acceleration[E_AXIS], MAX_ACCEL_EAXIS_DATA_VP); + delay(20); + + sendData(default_max_jerk[X_AXIS] * 100, MAX_JERK_XAXIS_DATA_VP); + sendData(default_max_jerk[Y_AXIS] * 100, MAX_JERK_YAXIS_DATA_VP); + sendData(default_max_jerk[Z_AXIS] * 100, MAX_JERK_ZAXIS_DATA_VP); + sendData(default_max_jerk[E_AXIS] * 100, MAX_JERK_EAXIS_DATA_VP); + delay(20); + + sendData(default_axis_steps_per_unit[X_AXIS] * 10, MAX_STEPSMM_XAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[Y_AXIS] * 10, MAX_STEPSMM_YAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[Z_AXIS] * 10, MAX_STEPSMM_ZAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[E_AXIS] * 10, MAX_STEPSMM_EAXIS_DATA_VP); + delay(20); + + sendData(default_nozzle_ptemp * 100, NOZZLE_TEMP_P_DATA_VP); + sendData(default_nozzle_itemp * 100, NOZZLE_TEMP_I_DATA_VP); + sendData(default_nozzle_dtemp * 100, NOZZLE_TEMP_D_DATA_VP); + delay(20); + + sendData(default_hotbed_ptemp * 100, HOTBED_TEMP_P_DATA_VP); + sendData(default_hotbed_itemp * 100, HOTBED_TEMP_I_DATA_VP); + sendData(default_hotbed_dtemp * 10, HOTBED_TEMP_D_DATA_VP); + delay(1000); + } + else if (recdat.data[0] == 14) { + if (!planner.has_blocks_queued()) { + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + } + } + else if (recdat.data[0] == 15) { + leveling_flag = false; + + gcode.process_subcommands_now(F("M420 S1")); // 退出调平界面 + if (!planner.has_blocks_queued()) { + sendData(10 * current_position.x, AXIS_X_COORD_VP); + sendData(10 * current_position.y, AXIS_Y_COORD_VP); + sendData(10 * current_position.z, AXIS_Z_COORD_VP); + sendData(ExchangePageBase + 21, ExchangepageAddr); + change_page_font = 21; + } + settings.save(); + st_bedNozzleHeightCal.isBedLeveling = false; + } + break; + + case BedLevelKey: + + if (recdat.data[0] == 1) { + gcode.process_subcommands_now(F("M420 S0")); + planner.synchronize(); + queue.enqueue_now(F("G28 Z0")); + queue.enqueue_now(F("M420 S0")); + queue.enqueue_one(F("G1 X110 Y110 F3000")); + queue.enqueue_now(F("G1 F200 Z0.0")); + } + else if (recdat.data[0] == 2) { + last_zoffset = zprobe_zoffset; + if (WITHIN((zprobe_zoffset + 0.05), -5.02, 5.02)) { + #if ENABLED(HAS_LEVELING) + zprobe_zoffset = (zprobe_zoffset + 0.05); + zprobe_zoffset = zprobe_zoffset - 0.0001; + #endif + babystep.add_mm(Z_AXIS, zprobe_zoffset - last_zoffset); + probe.offset.z = zprobe_zoffset; + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + } + } + else if (recdat.data[0] == 3) { + last_zoffset = zprobe_zoffset; + if (WITHIN((zprobe_zoffset - 0.05), -5.02, 5.02)) { + TERN_(HAS_LEVELING, zprobe_zoffset -= 0.0499); + babystep.add_mm(Z_AXIS, zprobe_zoffset - last_zoffset); + probe.offset.z = zprobe_zoffset; + } + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + } + else if (recdat.data[0] == 4) { + gcode.process_subcommands_now(F("M420 S0")); // Rock_20220817 进入调平页面先关掉自动补偿 + if (!planner.has_blocks_queued()) { + sendData(ExchangePageBase + 25, ExchangepageAddr); + change_page_font = 25; + queue.enqueue_one(F("G1 F200 Z3.0")); + queue.enqueue_one(F("G1 X110 Y110 F3000")); + queue.enqueue_one(F("G1 F200 Z0.0")); + } + } + else if (recdat.data[0] == 5) { + if (HMI_lcd_flag.home_flag) break; + gcode.process_subcommands_now(F("M420 S0")); // Rock_20220817 进入调平页面先关掉自动补偿 + // Bed Tramming, Centre 1 + if (!planner.has_blocks_queued()) { + waitway = 4; + queue.enqueue_now(F("G1 F600 Z3")); + queue.enqueue_now(F("G1 X110 Y110 F3000")); + queue.enqueue_now(F("G1 F600 Z0")); + waitway = 0; + } + + } + else if (recdat.data[0] == 6) { + // Bed Tramming, Front Left 2 + gcode.process_subcommands_now(F("M420 S0")); // Rock_20220817 进入调平页面先关掉自动补偿 + if (!planner.has_blocks_queued()) { + waitway = 4; + queue.enqueue_now(F("G1 F600 Z3")); + queue.enqueue_now(F("G1 X25 Y25 F3000")); + queue.enqueue_now(F("G1 F600 Z0")); + waitway = 0; + } + } + else if (recdat.data[0] == 7) { + // Bed Tramming, Front Right 3 + gcode.process_subcommands_now(F("M420 S0"));// Rock_20220817 进入调平页面先关掉自动补偿 + if (!planner.has_blocks_queued()) { + waitway = 4; + queue.enqueue_now(F("G1 F600 Z3")); + queue.enqueue_now(F("G1 X195 Y25 F3000")); + queue.enqueue_now(F("G1 F600 Z0")); + waitway = 0; + } + + } + else if (recdat.data[0] == 8) { + if (HMI_lcd_flag.home_flag) break; + gcode.process_subcommands_now(F("M420 S0"));// Rock_20220817 进入调平页面先关掉自动补偿 + // Bed Tramming, Back Right 4 + if (!planner.has_blocks_queued()) { + waitway = 4; + queue.enqueue_now(F("G1 F600 Z3")); + queue.enqueue_now(F("G1 X195 Y195 F3000")); + queue.enqueue_now(F("G1 F200 Z0")); + waitway = 0; + } + } + else if (recdat.data[0] == 9) { + // Bed Tramming, Back Left 5 + gcode.process_subcommands_now(F("M420 S0"));// Rock_20220817 进入调平页面先关掉自动补偿 + if (!planner.has_blocks_queued()) { + waitway = 4; + queue.enqueue_now(F("G1 F600 Z3")); + queue.enqueue_now(F("G1 X30 Y195 F3000")); + queue.enqueue_now(F("G1 F600 Z0")); + waitway = 0; + } + } + else if (recdat.data[0] == 10) { + gcode.process_subcommands_now(F("M420 S0"));// Rock_20220817 进入调平页面先关掉自动补偿 + sendData(0, AUTO_BED_LEVEL_TITLE_VP); + sendData(0, AUTO_LEVELING_PERCENT_DATA_VP); + if (!planner.has_blocks_queued()) { + sendData(ExchangePageBase + 26, ExchangepageAddr); + change_page_font = 26; + } + } + sendData(0, MOTOR_FREE_ICON_VP); + break; + + case AutoHomeKey: + if (recdat.data[0] == 1) { + AxisUnitMode = 1; + axis_unit = 10.0; + sendData(ExchangePageBase + 16, ExchangepageAddr); + change_page_font = 16; + sendData(3, MOVEAXIS_UNIT_ICON_VP); + } + else if (recdat.data[0] == 2) { + AxisUnitMode = 2; + axis_unit = 1.0; + sendData(ExchangePageBase + 17, ExchangepageAddr); + change_page_font = 17; + sendData(2, MOVEAXIS_UNIT_ICON_VP); + } + else if (recdat.data[0] == 3) { + AxisUnitMode = 3; + axis_unit = 0.1; + sendData(ExchangePageBase + 18, ExchangepageAddr); + change_page_font = 18; + sendData(1, MOVEAXIS_UNIT_ICON_VP); + } + else if (recdat.data[0] == 4) { + waitway = 4; + queue.enqueue_now(F("G28 X Y")); + g_uiXYAxisEnable = true; + update_time_value = 0; + sendData(0, MOTOR_FREE_ICON_VP); + } + else if (recdat.data[0] == 5) { + waitway = 4; + if ((axis_is_trusted(X_AXIS)) && (axis_is_trusted(Y_AXIS)) && (current_position.x >= 50) && (current_position.y >= 50)) { + queue.enqueue_now(F("G28 Z")); + g_uiZAxisEnable = true; + } + else { + queue.enqueue_now(F("G28")); + g_uiXYAxisEnable = true; + g_uiZAxisEnable = true; + } + sendData(0, MOTOR_FREE_ICON_VP); + update_time_value = 0; + } + + break; + + case XaxismoveKey: + if (!planner.has_blocks_queued()) { + float x_min, x_max; + waitway = 4; + x_min = 0; + x_max = X_MAX_POS; // rock_20220615 Change the X axis position not in the center + //x_max = X_MAX_POS - 8; + if (!g_uiXYAxisEnable) { // If the XYZ axis of the motor is not enabled, return to zero first + g_uiXYAxisEnable = true; + gcode.process_subcommands_now(F("G28 XY")); + if (g_uiZAxisEnable) + sendData(0, MOTOR_FREE_ICON_VP); + } + current_position.x = 0.1f * recdat.data[0]; + + LIMIT(current_position.x, x_min, x_max); + + RTS_line_to_current(X_AXIS); + sendData(10 * current_position.x, AXIS_X_COORD_VP); + delay(1); + sendData(0, MOTOR_FREE_ICON_VP); + waitway = 0; + } + else + sendData(10 * current_position.x, AXIS_X_COORD_VP); + break; + + case YaxismoveKey: + if (!planner.has_blocks_queued()) { + float y_min, y_max; + waitway = 4; + y_min = 0; + y_max = Y_MAX_POS; + if (!g_uiXYAxisEnable) { // If the XYZ axis of the motor is not enabled, return to zero first + g_uiXYAxisEnable = true; + gcode.process_subcommands_now(F("G28XY")); + if (g_uiZAxisEnable) sendData(0, MOTOR_FREE_ICON_VP); + } + + current_position.y = constrain(0.1f * recdat.data[0], y_min, y_max); + + RTS_line_to_current(Y_AXIS); + sendData(10 * current_position.y, AXIS_Y_COORD_VP); + delay(1); + sendData(0, MOTOR_FREE_ICON_VP); + waitway = 0; + } + else + sendData(10 * current_position.y, AXIS_Y_COORD_VP); + + break; + + case ZaxismoveKey: + if (!planner.has_blocks_queued()) { + waitway = 4; + float z_min = Z_MIN_POS, z_max = Z_MAX_POS - probe.offset.z; + if (!g_uiZAxisEnable) { // If the XYZ axis of the motor is not enabled, return to zero first + g_uiZAxisEnable = true; + g_uiXYAxisEnable = true; + gcode.process_subcommands_now(F("G28Z")); + if (g_uiXYAxisEnable) + sendData(0, MOTOR_FREE_ICON_VP); + } + current_position.z = constrain(0.1f * recdat.data[0], z_min, z_max); + RTS_line_to_current(Z_AXIS); + sendData(10 * current_position.z, AXIS_Z_COORD_VP); + delay(1); + sendData(0, MOTOR_FREE_ICON_VP); + waitway = 0; + } + else + sendData(10 * current_position.z, AXIS_Z_COORD_VP); + break; + + case HeaterLoadEnterKey: + if (!planner.has_blocks_queued()) { + queue.enqueue_now(F("G92 E0")); + FilamentLOAD = ((float)recdat.data[0]) / 10; + sendData(10 * FilamentLOAD, HEAD_FILAMENT_LOAD_DATA_VP); + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 46, ExchangepageAddr); + change_page_font = 46; + sendData(0, HEAD_FILAMENT_LOAD_DATA_VP); + break; + } + #endif + current_position.e += FilamentLOAD; + + if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, thermalManager.degHotend(0) - 6)) { + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + } + else if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, ChangeFilamentTemp - 6)) { + thermalManager.setTargetHotend(ChangeFilamentTemp, 0); + sendData(ChangeFilamentTemp, HEAD_SET_TEMP_VP); + } + g_heaterLoadTempAdd = true; + while (thermalManager.still_heating(0)) marlin.idle(); + g_heaterLoadTempAdd = false; + RTS_line_to_current(E_AXIS); + sendData(10 * FilamentLOAD, HEAD_FILAMENT_LOAD_DATA_VP); + planner.synchronize(); + } + else + sendData(0, HEAD_FILAMENT_LOAD_DATA_VP); + break; + + case HeaterUnLoadEnterKey: + if (!planner.has_blocks_queued()) { + queue.enqueue_now(F("G92 E0")); + FilamentUnLOAD = ((float)recdat.data[0]) / 10; + sendData(10 * FilamentUnLOAD, HEAD_FILAMENT_UNLOAD_DATA_VP); + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 46, ExchangepageAddr); + change_page_font = 46; + sendData(0, HEAD_FILAMENT_UNLOAD_DATA_VP); + break; + } + #endif + current_position.e -= FilamentUnLOAD; + + if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, thermalManager.degHotend(0) - 6)) { + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + } + else if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, ChangeFilamentTemp - 6)) { + thermalManager.setTargetHotend(ChangeFilamentTemp, 0); + sendData(ChangeFilamentTemp, HEAD_SET_TEMP_VP); + } + g_heaterLoadTempAdd = true; + while (thermalManager.still_heating(0)) marlin.idle(); + g_heaterLoadTempAdd = false; + RTS_line_to_current(E_AXIS); + sendData(10 * FilamentUnLOAD, HEAD_FILAMENT_UNLOAD_DATA_VP); + planner.synchronize(); + } + else + sendData(0, HEAD_FILAMENT_UNLOAD_DATA_VP); + break; + + case HeaterLoadStartKey: + if (recdat.data[0] == 1) { + if (!planner.has_blocks_queued()) { + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 46, ExchangepageAddr); + change_page_font = 46; + break; + } + #endif + + if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, thermalManager.degHotend(0) - 6)) { + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + break; + } + else if (WITHIN(thermalManager.degTargetHotend(0), EXTRUDE_MINTEMP, ChangeFilamentTemp - 6)) { + thermalManager.setTargetHotend(ChangeFilamentTemp, 0); + sendData(ChangeFilamentTemp, HEAD_SET_TEMP_VP); + break; + } + else { + RTS_line_to_current(E_AXIS); + planner.synchronize(); + } + sendData(ExchangePageBase + 19, ExchangepageAddr); + change_page_font = 19; + } + } + else if (recdat.data[0] == 2) { + if (!planner.has_blocks_queued()) { + sendData(ExchangePageBase + 19, ExchangepageAddr); + change_page_font = 19; + } + } + else if (recdat.data[0] == 3) { + queue.enqueue_now(F("G92 E0")); // rock_20210927 liuxu Reset Extruder + sendData(ExchangePageBase + 19, ExchangepageAddr); + change_page_font = 19; + sendData(0, HEAD_FILAMENT_LOAD_DATA_VP); + sendData(0, HEAD_FILAMENT_UNLOAD_DATA_VP); + } + break; + + case SelectLanguageKey: + if (recdat.data[0] > 0) ui.set_language(recdat.data[0] - 1); + for (int i = 0; i < 9; i++) sendData(0, LANGUAGE_CHINESE_TITLE_VP + i); + sendData(1, LANGUAGE_CHINESE_TITLE_VP + ui.language); + updateLanguageDisplay(); + settings.save(); + break; + + case PowerContinuePrintKey: + if (recdat.data[0] == 1) { + if (recovery.recovery_flag && PoweroffContinue) { + power_off_type_yes = true; + update_time_value = 0; + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + //recovery.resume(); + queue.enqueue_now(F("M1000")); + + sdcard_pause_check = true; + zprobe_zoffset = probe.offset.z; + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + g_cloudPLRStatusValue = CLOUD_PLR_YES_STATE; + // 3:cloud print resume + SERIAL_ECHOLNPGM("M79 S3"); + } + else if (!PoweroffContinue) { + SERIAL_ECHOLNPGM("M79 S3"); + queue.enqueue_now(F("M79 S3")); // 3:cloud print resume + } + } + else if (recdat.data[0] == 2) { + if (PoweroffContinue) { + update_time_value = RTS_UPDATE_VALUE; + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + + sendData(0, PRINT_TIME_HOUR_VP); + sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + sdCardStop(); + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + } + else if (!PoweroffContinue) { + SERIAL_ECHOLNPGM("M79 S4"); + queue.enqueue_now(F("M79 S4")); // 4:cloud print stop + } + } + break; + + case PLAHeadSetEnterKey: + ui.material_preset[0].hotend_temp = recdat.data[0]; + sendData(ui.material_preset[0].hotend_temp, PREHEAT_PLA_SET_NOZZLE_TEMP_VP); + break; + + case PLABedSetEnterKey: + ui.material_preset[0].bed_temp = recdat.data[0]; + sendData(ui.material_preset[0].bed_temp, PREHEAT_PLA_SET_BED_TEMP_VP); + break; + + case ABSHeadSetEnterKey: + ui.material_preset[1].hotend_temp = recdat.data[0]; + sendData(ui.material_preset[1].hotend_temp, PREHEAT_ABS_SET_NOZZLE_TEMP_VP); + break; + + case ABSBedSetEnterKey: + ui.material_preset[1].bed_temp = recdat.data[0]; + sendData(ui.material_preset[1].bed_temp, PREHEAT_ABS_SET_BED_TEMP_VP); + break; + + case StoreMemoryKey: + if (recdat.data[0] == 1) { + sendData(ExchangePageBase + 37, ExchangepageAddr); + change_page_font = 37; + } + if (recdat.data[0] == 2) { + //queue.enqueue_now(F("M502")); + ui.set_language(1); + updateLanguageDisplay(); + for (int i = 0; i < 9; i++) sendData(0, LANGUAGE_CHINESE_TITLE_VP + i); + sendData(1, LANGUAGE_CHINESE_TITLE_VP + ui.language); + last_zoffset = zprobe_zoffset = probe.offset.z = 0; + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + // settings.save(); + ui.material_preset[0].hotend_temp = PREHEAT_1_TEMP_HOTEND; + ui.material_preset[0].bed_temp = PREHEAT_1_TEMP_BED; + ui.material_preset[1].hotend_temp = PREHEAT_2_TEMP_HOTEND; + ui.material_preset[1].bed_temp = PREHEAT_2_TEMP_BED; + sendData(ui.material_preset[0].hotend_temp, PREHEAT_PLA_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[0].bed_temp, PREHEAT_PLA_SET_BED_TEMP_VP); + sendData(ui.material_preset[1].hotend_temp, PREHEAT_ABS_SET_NOZZLE_TEMP_VP); + sendData(ui.material_preset[1].bed_temp, PREHEAT_ABS_SET_BED_TEMP_VP); + delay(20); + + sendData(default_max_feedrate[X_AXIS], MAX_VELOCITY_XAXIS_DATA_VP); + sendData(default_max_feedrate[Y_AXIS], MAX_VELOCITY_YAXIS_DATA_VP); + sendData(default_max_feedrate[Z_AXIS], MAX_VELOCITY_ZAXIS_DATA_VP); + sendData(default_max_feedrate[E_AXIS], MAX_VELOCITY_EAXIS_DATA_VP); + delay(20); + + sendData(default_max_acceleration[X_AXIS], MAX_ACCEL_XAXIS_DATA_VP); + sendData(default_max_acceleration[Y_AXIS], MAX_ACCEL_YAXIS_DATA_VP); + sendData(default_max_acceleration[Z_AXIS], MAX_ACCEL_ZAXIS_DATA_VP); + sendData(default_max_acceleration[E_AXIS], MAX_ACCEL_EAXIS_DATA_VP); + delay(20); + + sendData(default_max_jerk[X_AXIS] * 100, MAX_JERK_XAXIS_DATA_VP); + sendData(default_max_jerk[Y_AXIS] * 100, MAX_JERK_YAXIS_DATA_VP); + sendData(default_max_jerk[Z_AXIS] * 100, MAX_JERK_ZAXIS_DATA_VP); + sendData(default_max_jerk[E_AXIS] * 100, MAX_JERK_EAXIS_DATA_VP); + delay(20); + + sendData(default_axis_steps_per_unit[X_AXIS] * 10, MAX_STEPSMM_XAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[Y_AXIS] * 10, MAX_STEPSMM_YAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[Z_AXIS] * 10, MAX_STEPSMM_ZAXIS_DATA_VP); + sendData(default_axis_steps_per_unit[E_AXIS] * 10, MAX_STEPSMM_EAXIS_DATA_VP); + delay(20); + + sendData(default_nozzle_ptemp * 100, NOZZLE_TEMP_P_DATA_VP); + sendData(default_nozzle_itemp * 100, NOZZLE_TEMP_I_DATA_VP); + sendData(default_nozzle_dtemp * 100, NOZZLE_TEMP_D_DATA_VP); + delay(20); + sendData(default_hotbed_ptemp * 100, HOTBED_TEMP_P_DATA_VP); + sendData(default_hotbed_itemp * 100, HOTBED_TEMP_I_DATA_VP); + sendData(default_hotbed_dtemp * 10, HOTBED_TEMP_D_DATA_VP); + delay(20); + settings.reset(); // rock_20220816 + delay(50); + settings.save(); + delay(200); + } + else if (recdat.data[0] == 3) { + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + } + else if (recdat.data[0] == 4) { + sendData(ExchangePageBase + 34, ExchangepageAddr); + change_page_font = 34; + } + else if (recdat.data[0] == 5) { + sendData(ExchangePageBase + 39, ExchangepageAddr); + change_page_font = 39; + } + else if (recdat.data[0] == 6) { + wifi_enable_flag ^= true; + queue.inject(F("M115")); // TODO: Report new WIFI state (not all of M115) + RTS_UpdateWifi(); + settings.save(); + } + else if (recdat.data[0] == 7) { + sendData(ExchangePageBase + 38, ExchangepageAddr); + change_page_font = 38; + } + else if (recdat.data[0] == 8) { + sendData(ExchangePageBase + 36, ExchangepageAddr); + change_page_font = 36; + } + else if (recdat.data[0] == 9) { + sendData(ExchangePageBase + 37, ExchangepageAddr); + change_page_font = 37; + } + else if (recdat.data[0] == 10) { + sendData(ExchangePageBase + 35, ExchangepageAddr); + change_page_font = 35; + } + else if (recdat.data[0] == 11) { + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + settings.save(); + delay(1000); + } + else if (recdat.data[0] == 12) { + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + settings.save(); + delay(1000); + } + break; + + case FanSpeedEnterKey: + thermalManager.fan_speed[0] = recdat.data[0]; + sendData(thermalManager.fan_speed[0], FAN_SPEED_CONTROL_DATA_VP); + break; + + case VelocityXaxisEnterKey: { + const float velocity_xaxis = recdat.data[0]; + sendData(velocity_xaxis, MAX_VELOCITY_XAXIS_DATA_VP); + planner.set_max_feedrate(X_AXIS, velocity_xaxis); + } break; + + case VelocityYaxisEnterKey: { + const float velocity_yaxis = recdat.data[0]; + sendData(velocity_yaxis, MAX_VELOCITY_YAXIS_DATA_VP); + planner.set_max_feedrate(Y_AXIS, velocity_yaxis); + } break; + + case VelocityZaxisEnterKey: { + const float velocity_zaxis = recdat.data[0]; + sendData(velocity_zaxis, MAX_VELOCITY_ZAXIS_DATA_VP); + planner.set_max_feedrate(Z_AXIS, velocity_zaxis); + } break; + + case VelocityEaxisEnterKey: { + const float velocity_eaxis = recdat.data[0]; + sendData(velocity_eaxis, MAX_VELOCITY_EAXIS_DATA_VP); + planner.set_max_feedrate(E_AXIS, velocity_eaxis); + } break; + + case AccelXaxisEnterKey: { + const float accel_xaxis = recdat.data[0]; + sendData(accel_xaxis, MAX_ACCEL_XAXIS_DATA_VP); + planner.set_max_acceleration(X_AXIS, accel_xaxis); + } break; + + case AccelYaxisEnterKey: { + const float accel_yaxis = recdat.data[0]; + sendData(accel_yaxis, MAX_ACCEL_YAXIS_DATA_VP); + planner.set_max_acceleration(Y_AXIS, accel_yaxis); + } break; + + case AccelZaxisEnterKey: { + const float accel_zaxis = recdat.data[0]; + sendData(accel_zaxis, MAX_ACCEL_ZAXIS_DATA_VP); + planner.set_max_acceleration(Z_AXIS, accel_zaxis); + } break; + + case AccelEaxisEnterKey: { + const float accel_eaxis = recdat.data[0]; + sendData(accel_eaxis, MAX_ACCEL_EAXIS_DATA_VP); + planner.set_max_acceleration(E_AXIS, accel_eaxis); + } break; + + case JerkXaxisEnterKey: { + const float jerk_xaxis = (float)recdat.data[0] / 100; + sendData(jerk_xaxis * 100, MAX_JERK_XAXIS_DATA_VP); + planner.set_max_jerk(X_AXIS, jerk_xaxis); + } break; + + case JerkYaxisEnterKey: { + const float jerk_yaxis = (float)recdat.data[0] / 100; + sendData(jerk_yaxis * 100, MAX_JERK_YAXIS_DATA_VP); + planner.set_max_jerk(Y_AXIS, jerk_yaxis); + } break; + + case JerkZaxisEnterKey: { + const float jerk_zaxis = (float)recdat.data[0] / 100; + sendData(jerk_zaxis * 100, MAX_JERK_ZAXIS_DATA_VP); + planner.set_max_jerk(Z_AXIS, jerk_zaxis); + } break; + + case JerkEaxisEnterKey: { + const float jerk_eaxis = (float)recdat.data[0] / 100; + sendData(jerk_eaxis * 100, MAX_JERK_EAXIS_DATA_VP); + planner.set_max_jerk(E_AXIS, jerk_eaxis); + } break; + + case StepsmmXaxisEnterKey: { + const float stepsmm_xaxis = (float)recdat.data[0] / 10; + sendData(stepsmm_xaxis * 10, MAX_STEPSMM_XAXIS_DATA_VP); + planner.settings.axis_steps_per_mm[X_AXIS] = stepsmm_xaxis; + } break; + + case StepsmmYaxisEnterKey: { + const float stepsmm_yaxis = (float)recdat.data[0] / 10; + sendData(stepsmm_yaxis * 10, MAX_STEPSMM_YAXIS_DATA_VP); + planner.settings.axis_steps_per_mm[Y_AXIS] = stepsmm_yaxis; + } break; + + case StepsmmZaxisEnterKey: { + const float stepsmm_zaxis = (float)recdat.data[0] / 10; + sendData(stepsmm_zaxis * 10, MAX_STEPSMM_ZAXIS_DATA_VP); + planner.settings.axis_steps_per_mm[Z_AXIS] = stepsmm_zaxis; + } break; + + case StepsmmEaxisEnterKey: { + const float stepsmm_eaxis = (float)recdat.data[0] / 10; + sendData(stepsmm_eaxis * 10, MAX_STEPSMM_EAXIS_DATA_VP); + planner.settings.axis_steps_per_mm[E_AXIS] = stepsmm_eaxis; + } break; + + case NozzlePTempEnterKey: { + const float nozzle_ptemp = (float)recdat.data[0] / 100; + sendData(nozzle_ptemp * 100, NOZZLE_TEMP_P_DATA_VP); + thermalManager.temp_hotend[0].pid.set_Kp(nozzle_ptemp); + } break; + + case NozzleITempEnterKey: { + const float nozzle_itemp = (float)recdat.data[0] / 100; + sendData(nozzle_itemp * 100, NOZZLE_TEMP_I_DATA_VP); + thermalManager.temp_hotend[0].pid.set_Ki(nozzle_itemp); + } break; + + case NozzleDTempEnterKey: { + const float nozzle_dtemp = (float)recdat.data[0] / 100; + sendData(nozzle_dtemp * 100, NOZZLE_TEMP_D_DATA_VP); + thermalManager.temp_hotend[0].pid.set_Kd(nozzle_dtemp); + } break; + + case HotbedPTempEnterKey: { + const float hotbed_ptemp = (float)recdat.data[0] / 100; + sendData(hotbed_ptemp * 100, HOTBED_TEMP_P_DATA_VP); + thermalManager.temp_bed.pid.set_Kp(hotbed_ptemp); + } break; + + case HotbedITempEnterKey: { + const float hotbed_itemp = (float)recdat.data[0] / 100; + sendData(hotbed_itemp * 100, HOTBED_TEMP_I_DATA_VP); + thermalManager.temp_bed.pid.set_Ki(hotbed_itemp); + } break; + + case HotbedDTempEnterKey: { + const float hotbed_dtemp = (float)recdat.data[0] / 10; + sendData(hotbed_dtemp * 10, HOTBED_TEMP_D_DATA_VP); + thermalManager.temp_bed.pid.set_Kd(hotbed_dtemp); + } break; + + case SelectFileKey: + if (sdDetected()) { + if (recdat.data[0] > CardRecbuf.Filesum) break; + CardRecbuf.selectFlag = true; + CardRecbuf.recordcount = recdat.data[0] - 1; + + for (int j = 0; j < 20; j++) sendData(0, SELECT_FILE_TEXT_VP + j); + delay(2); + for (int j = 1; j <= CardRecbuf.Filesum; j++) { + sendData((unsigned long)0x073F, FilenameNature + j * 16); + sendData(0, FILE1_SELECT_ICON_VP - 1 + j); + } + sendData((unsigned long)0xFFFF, FilenameNature + recdat.data[0] * 16); + sendData(1, FILE1_SELECT_ICON_VP + (recdat.data[0] - 1)); + } + + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + delay(20); + sendData(CardRecbuf.Cardshowfilename[CardRecbuf.recordcount], SELECT_FILE_TEXT_VP); + break; + + case StartFileKey: + if ((recdat.data[0] == 1) && sdDetected()) { + + if (CardRecbuf.recordcount < 0 || !CardRecbuf.selectFlag) break; + + if (card.flag.mounted) { + char cmd[30]; + char *c; + sprintf_P(cmd, PSTR("M23 %s"), CardRecbuf.Cardfilename[CardRecbuf.recordcount]); + for (c = &cmd[4]; *c; c++) *c = tolower(*c); + + ZERO(cmdbuf); + strcpy(cmdbuf, cmd); + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if (runout.enabled && runout.filament_ran_out) { + sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + sdcard_pause_check = false; + break; + } + #endif + PoweroffContinue = true; + queue.enqueue_one_now(cmd); + delay(20); + queue.enqueue_now(F("M24")); + // clean screen. + for (int j = 0; j < 20; j++) sendData(0, PRINT_FILE_TEXT_VP + j); + + sendData(CardRecbuf.Cardshowfilename[CardRecbuf.recordcount], PRINT_FILE_TEXT_VP); + + delay(2); + //DEBUG_ECHO_MSG("\nrock_20220411_check_filament\n"); + marlin.end_waiting(); + TERN_(BABYSTEPPING, sendData(0, AUTO_BED_LEVEL_ZOFFSET_VP)); + feedrate_percentage = 100; + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + sendData(ExchangePageBase + 10, ExchangepageAddr); + queue.enqueue_now(F("G28 X Y"));// rock_20220707 解决选中文件打印加热烫平台的问题 + update_time_value = 0; + // 1:cloud print start + SERIAL_ECHOLNPGM("M79 S1"); + } + else + break; + } + else if (recdat.data[0] == 2) { + if (!planner.has_blocks_queued()) { + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + if ((file_total_page > file_current_page) && (file_current_page < (MaxFileNumber / 4))) + file_current_page++; + else + break; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + sendData(ExchangePageBase + 2, ExchangepageAddr); + change_page_font = 2; + + if (card.flag.mounted) + RTS_line_to_filelist(); + } + } + else if (recdat.data[0] == 3) { + if (!planner.has_blocks_queued()) { + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + if (file_current_page > 1) + file_current_page--; + else + break; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + sendData(ExchangePageBase + 2, ExchangepageAddr); + change_page_font = 2; + + if (card.flag.mounted) + RTS_line_to_filelist(); + } + } + else if (recdat.data[0] == 4) { + if (!planner.has_blocks_queued()) { + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + file_current_page = 1; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + + RTS_line_to_filelist(); + + sendData(ExchangePageBase + 2, ExchangepageAddr); + change_page_font = 2; + } + } + else if (recdat.data[0] == 5) { + if (!planner.has_blocks_queued()) { + sendData(file_total_page, PRINT_COUNT_PAGE_DATA_VP); + file_current_page = file_total_page; + sendData(file_current_page, PRINT_CURRENT_PAGE_DATA_VP); + + RTS_line_to_filelist(); + + sendData(ExchangePageBase + 2, ExchangepageAddr); + change_page_font = 2; + } + } + break; + + case ChangePageKey: + sendData(CardRecbuf.Cardshowfilename[CardRecbuf.recordcount], PRINT_FILE_TEXT_VP); + + // represents to update file list + if (CardUpdate && lcd_sd_status && card.isSDCardInserted()) { + RTS_line_to_filelist(); + for (uint16_t i = 0; i < 5; i++) { + delay(1); + sendData((unsigned long)0xFFFF, FilenameNature + (i + 1) * 16); + sendData(0, FILE1_SELECT_ICON_VP + i); + } + } + + sendData(MACHINE_NAME, MACHINE_NAME_ABOUT_TEXT_VP); + sendData(FIRMWARE_VERSION, FIRMWARE_VERSION_ABOUT_TEXT_VP); + //sendData(SCREEN_VERSION, PRINTER_DISPLAY_VERSION_TEXT_VP); + sendData(HARDWARE_VERSION, HARDWARE_VERSION_ABOUT_TEXT_VP); + sendData(PRINT_SIZE, PRINTER_PRINTSIZE_TEXT_VP); + + sendData(ui.language == 0 ? CORP_WEBSITE_C : CORP_WEBSITE_E, WEBSITE_ABOUT_TEXT_VP); + + sendData(thermalManager.fan_speed[0] ? 1 : 0, PRINTER_FANOPEN_TITLE_VP); + sendData(LEDStatus ? 1 : 0, PRINTER_LEDOPEN_TITLE_VP); + + //Percentrecord = card.percentDone() + 1; + //if (Percentrecord <= 100) { + // sendData((unsigned char)Percentrecord, PRINT_PROCESS_ICON_VP); + //} + sendData(card.percentDone(), PRINT_PROCESS_VP); + + sendData(zprobe_zoffset * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + + sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + #if ENABLED(BED_TEMP_COMP) + if (WITHIN(thermalManager.degTargetBed(), 66, 85)) + sendData(thermalManager.degTargetBed() - 5, BED_SET_TEMP_VP); + else if (WITHIN(thermalManager.degTargetBed(), 86, 127)) + sendData(thermalManager.degTargetBed() - 7, BED_SET_TEMP_VP); + #else + sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + #endif + //sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + updateLanguageDisplay(); + + sendData(change_page_font + ExchangePageBase, ExchangepageAddr); + break; + + case ErrorKey: + if (recdat.data[0] == 1) { + if (printingIsActive()) { + sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + } + else if (printingIsPaused()) { + sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + else { + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + + if (errorway == 4) hal.reboot(); // reboot + } + break; + + default: break; + } + memset(&recdat, 0, sizeof(recdat)); + recdat.head[0] = FHONE; + recdat.head[1] = FHTWO; +} + +/** + * @brief Update the state of the UI + * @details Called frequently from RTS_Update() + */ +void RTS::eachMomentUpdate() { + const millis_t ms = millis(); + + if (flag_counter_wifi_reset) { + millis_t ms_3 = millis(); + if (ms_3 > next_wifireset_update_ms) { + next_wifireset_update_ms = ms_3 + 1000; + wifiresetcount_ms++; + sendData((TIME_WIFI_RESET_BACKPAGE - wifiresetcount_ms), WIFI_RESET_REMAIN_TIME_DATA_VP); + } + + if (wifiresetcount_ms > TIME_WIFI_RESET_BACKPAGE) { + flag_counter_wifi_reset = false; + sendData(0, WIFI_CONNECTED_DISPLAY_ICON_VP); + sendData(ExchangePageBase + 33, ExchangepageAddr); + change_page_font = 33; + } + } + else + wifiresetcount_ms = 0; + + if (ms > next_rts_update_ms) { + // print the file before the power is off. + if (!power_off_type_yes && lcd_sd_status && recovery.recovery_flag) { + sendData(ExchangePageBase, ExchangepageAddr); + if (startprogress < 80) sendData(startprogress, START_PROCESS_ICON_VP); + delay(30); + if (++startprogress > 80) { + sendData(StartSoundSet, SoundAddr); + power_off_type_yes = true; + + fileCnt = card.get_num_items(); + card.getWorkDirName(); + if (card.filename[0] != '/') card.cdup(); + + for (uint16_t i = 0; (i < fileCnt) && (i < MaxFileNumber); i++) { + card.selectFileByIndex(fileCnt - 1 - i); + char *pointFilename = card.longFilename; + int filenamelen = strlen(card.longFilename); + int j = 1; + while ((strncmp(&pointFilename[j], ".gcode", 6) && strncmp(&pointFilename[j], ".GCODE", 6)) && ((j++) < filenamelen)); + + for (int j = 0; j < 20; j++) sendData(0, PRINT_FILE_TEXT_VP + j); + + if (j >= TEXTBYTELEN) { + strncpy(&card.longFilename[TEXTBYTELEN - 3], "..", 2); + card.longFilename[TEXTBYTELEN - 1] = '\0'; + j = TEXTBYTELEN - 1; + } + + strncpy(CardRecbuf.Cardshowfilename[i], card.longFilename, j); + + strcpy(CardRecbuf.Cardfilename[i], card.filename); + CardRecbuf.addr[i] = PRINT_FILE_TEXT_VP + 20; + sendData(CardRecbuf.Cardshowfilename[i], CardRecbuf.addr[i]); + if (!strcmp(CardRecbuf.Cardfilename[i], &recovery.info.sd_filename[1])) { + sendData(CardRecbuf.Cardshowfilename[i], PRINT_FILE_TEXT_VP); + break; + } + } + sendData(ExchangePageBase + 27, ExchangepageAddr); + change_page_font = 27; + PoweroffContinue = true; + g_cloudPLRStatusValue = CLOUD_PLR_CHOOSE_STATE; // 云打印断电续打的选择界面 + SERIAL_ECHOLNPGM("M79 S6"); // 6:cloud print power continue + } + return; + } + + if (!power_off_type_yes && !recovery.recovery_flag) { + sendData(ExchangePageBase, ExchangepageAddr); + if (startprogress < 80) sendData(startprogress, START_PROCESS_ICON_VP); + delay(30); + if (++startprogress > 80) { + sendData(StartSoundSet, SoundAddr); + power_off_type_yes = true; + update_time_value = RTS_UPDATE_VALUE; + sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + } + return; + } + + static unsigned char last_cardpercentValue = 100; + #if HAS_MEDIA + if (PoweroffContinue) { + duration_t elapsed = print_job_timer.duration(); + sendData(elapsed.value / 3600, PRINT_TIME_HOUR_VP); + sendData((elapsed.value % 3600) / 60, PRINT_TIME_MIN_VP); + } + #endif + + const uint8_t pct = card.percentDone(); + + if (card.isPrinting() && last_cardpercentValue != pct) { + if (pct > 0) { + Percentrecord = pct; + if (Percentrecord <= 100) + sendData((unsigned char)Percentrecord, PRINT_PROCESS_ICON_VP); + } + else + sendData(0, PRINT_PROCESS_ICON_VP); + + sendData(pct, PRINT_PROCESS_VP); + last_cardpercentValue = pct; + sendData(10.0f * current_position.z, AXIS_Z_COORD_VP); + } + + if (pause_action_flag && !sdcard_pause_check && printingIsPaused() && !planner.has_blocks_queued()) { + pause_action_flag = false; + queue.enqueue_now(F("G0 F3000 X220 Y220")); // rock_20220704 + thermalManager.setTargetHotend(0, 0); + sendData(0, HEAD_SET_TEMP_VP); + } + + sendData(thermalManager.degHotend(0), HEAD_CURRENT_TEMP_VP); + + #if ENABLED(BED_TEMP_COMP) + float bedTempDisp = thermalManager.degBed(); + if (WITHIN(thermalManager.degTargetBed(), 66, 127)) { + if (WITHIN(bedTempDisp, 66, 86)) + bedTempDisp -= (5 * bedTempDisp) / thermalManager.degTargetBed(); + else if (WITHIN(bedTempDisp, 87, 127)) + bedTempDisp -= (7 * bedTempDisp) / thermalManager.degTargetBed(); + } + sendData(bedTempDisp, BED_CURRENT_TEMP_VP); + #else + sendData(thermalManager.degBed(), BED_CURRENT_TEMP_VP); + #endif + + #if HAS_MEDIA + + if (sd_printing_autopause && PoweroffContinue) { + if (sdcard_pause_check) { + sendData(0, CHANGE_SDCARD_ICON_VP); + sdcard_pause_check = false; + } + } + + //if (!sdcard_pause_check && !card.isPrinting() && !planner.has_blocks_queued()) + if (HMI_lcd_flag.remove_card_flag) { + //if (card.flag.mounted) + if (temp_remove_card_flag && !planner.has_blocks_queued()) { + queue.inject(F("G1 F1200 X220 Y220")); + temp_remove_card_flag = false; + //queue.enqueue_now(F("G28 X220 Y220")); + } + sendData(card.isSDCardInserted() ? 1 : 0, CHANGE_SDCARD_ICON_VP); + } + + #endif // HAS_MEDIA + + if (last_target_temperature[0] != thermalManager.degTargetHotend(0) || last_target_temperature_bed != thermalManager.degTargetBed()) { + //thermalManager.setTargetHotend(thermalManager.degTargetHotend(0), 0); + //thermalManager.setTargetBed(thermalManager.degTargetBed()); + sendData(thermalManager.degTargetHotend(0), HEAD_SET_TEMP_VP); + #if ENABLED(BED_TEMP_COMP) + if (WITHIN(thermalManager.degTargetBed(), 66, 85)) + sendData(thermalManager.degTargetBed() - 5, BED_SET_TEMP_VP); + else if (WITHIN(thermalManager.degTargetBed(), 86, 127)) + sendData(thermalManager.degTargetBed() - 7, BED_SET_TEMP_VP); + #else + sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + #endif + //sendData(thermalManager.degTargetBed(), BED_SET_TEMP_VP); + last_target_temperature[0] = thermalManager.degTargetHotend(0); + last_target_temperature_bed = thermalManager.degTargetBed(); + } + + //static bool heatway = false; + //if (heatway && thermalManager.degHotend(0) >= thermalManager.degTargetHotend(0)) { + // sendData(ExchangePageBase + 19, ExchangepageAddr); + // change_page_font = 19; + // heatway = false; + // sendData(10 * FilamentLOAD, HEAD_FILAMENT_LOAD_DATA_VP); + // sendData(10 * FilamentUnLOAD, HEAD_FILAMENT_UNLOAD_DATA_VP); + //} + + TERN_(FILAMENT_RUNOUT_SENSOR, sendData(runout.filament_ran_out ? 0 : 1, FILAMENT_LOAD_ICON_VP)); + + next_rts_update_ms = ms + RTS_UPDATE_INTERVAL + update_time_value; + } +} + +void RTS::updateLanguageDisplay() { + auto RTS_SndLangData = [](const uint16_t v) { + sendData(ui.language + 1, v); + }; + RTS_SndLangData(MAIN_PAGE_BLUE_TITLE_VP); + RTS_SndLangData(SELECT_FILE_BLUE_TITLE_VP); + RTS_SndLangData(PREPARE_PAGE_BLUE_TITLE_VP); + RTS_SndLangData(SETTING_PAGE_BLUE_TITLE_VP); + RTS_SndLangData(MAIN_PAGE_BLACK_TITLE_VP); + RTS_SndLangData(SELECT_FILE_BLACK_TITLE_VP); + RTS_SndLangData(PREPARE_PAGE_BLACK_TITLE_VP); + RTS_SndLangData(SETTING_PAGE_BLACK_TITLE_VP); + + RTS_SndLangData(PRINT_ADJUST_MENT_TITLE_VP); + RTS_SndLangData(PRINT_SPEED_TITLE_VP); + RTS_SndLangData(HEAD_SET_TITLE_VP); + RTS_SndLangData(BED_SET_TITLE_VP); + RTS_SndLangData(LEVEL_ZOFFSET_TITLE_VP); + RTS_SndLangData(FAN_CONTROL_TITLE_VP); + RTS_SndLangData(LED_CONTROL_TITLE_VP); + + RTS_SndLangData(MOVE_AXIS_ENTER_GREY_TITLE_VP); + RTS_SndLangData(CHANGE_FILAMENT_GREY_TITLE_VP); + RTS_SndLangData(PREHEAT_PAGE_GREY_TITLE_VP); + RTS_SndLangData(MOVE_AXIS_ENTER_BLACK_TITLE_VP); + RTS_SndLangData(CHANGE_FILAMENT_BLACK_TITLE_VP); + RTS_SndLangData(PREHEAT_PAGE_BLACK_TITLE_VP); + + RTS_SndLangData(PREHEAT_PLA_BUTTON_TITLE_VP); + RTS_SndLangData(PREHEAT_ABS_BUTTON_TITLE_VP); + RTS_SndLangData(COOL_DOWN_BUTTON_TITLE_VP); + + RTS_SndLangData(FILAMENT_LOAD_BUTTON_TITLE_VP); + RTS_SndLangData(FILAMENT_UNLOAD_BUTTON_TITLE_VP); + + RTS_SndLangData(LANGUAGE_SELECT_ENTER_VP); + RTS_SndLangData(FACTORY_DEFAULT_ENTER_TITLE_VP); + RTS_SndLangData(LEVELING_PAGE_TITLE_VP); + + RTS_SndLangData(PRINTER_DEVICE_GREY_TITLE_VP); + RTS_SndLangData(PRINTER_ADVINFO_GREY_TITLE_VP); + RTS_SndLangData(PRINTER_INFO_ENTER_GREY_TITLE_VP); + RTS_SndLangData(PRINTER_DEVICE_BLACK_TITLE_VP); + RTS_SndLangData(PRINTER_ADVINFO_BLACK_TITLE_VP); + RTS_SndLangData(PRINTER_INFO_ENTER_BLACK_TITLE_VP); + + RTS_SndLangData(PREHEAT_PLA_SET_TITLE_VP); + RTS_SndLangData(PREHEAT_ABS_SET_TITLE_VP); + + RTS_SndLangData(STORE_MEMORY_CONFIRM_TITLE_VP); + RTS_SndLangData(STORE_MEMORY_CANCEL_TITLE_VP); + + RTS_SndLangData(FILAMENT_UNLOAD_IGNORE_TITLE_VP); + RTS_SndLangData(FILAMENT_USEUP_TITLE_VP); + RTS_SndLangData(BUTTON_CHECK_CONFIRM_TITLE_VP); + RTS_SndLangData(BUTTON_CHECK_CANCEL_TITLE_VP); + RTS_SndLangData(FILAMENT_LOAD_TITLE_VP); + RTS_SndLangData(FILAMENT_LOAD_RESUME_TITLE_VP); + RTS_SndLangData(PAUSE_PRINT_POP_TITLE_VP); + RTS_SndLangData(STOP_PRINT_POP_TITLE_VP); + RTS_SndLangData(POWERCONTINUE_POP_TITLE_VP); + RTS_SndLangData(AUTO_HOME_WAITING_POP_TITLE_VP); + + RTS_SndLangData(BEDLEVELING_WAIT_TITLE_VP); + RTS_SndLangData(RESTORE_FACTORY_TITLE_VP); + RTS_SndLangData(RESET_WIFI_SETTING_TITLE_VP); + RTS_SndLangData(KILL_THERMAL_RUNAWAY_TITLE_VP); + RTS_SndLangData(KILL_HEATING_FAIL_TITLE_VP); + RTS_SndLangData(KILL_THERMISTOR_ERROR_TITLE_VP); + RTS_SndLangData(WIND_AUTO_SHUTDOWN_TITLE_VP); + RTS_SndLangData(RESET_WIFI_SETTING_BUTTON_VP); + RTS_SndLangData(PRINTER_AUTO_SHUTDOWN_TITLE_VP); + RTS_SndLangData(WIND_AUTO_SHUTDOWN_PAGE_VP); + RTS_SndLangData(AUTO_LEVELING_START_TITLE_VP); + RTS_SndLangData(AUX_LEVELING_GREY_TITLE_VP); + RTS_SndLangData(AUTO_LEVELING_GREY_TITLE_VP); + RTS_SndLangData(AUX_LEVELING_BLACK_TITLE_VP); + RTS_SndLangData(AUTO_LEVELING_BLACK_TITLE_VP); + RTS_SndLangData(LANGUAGE_SELECT_PAGE_TITLE_VP); + RTS_SndLangData(ADV_SETTING_MOTION_TITLE_VP); + RTS_SndLangData(ADV_SETTING_PID_TITLE_VP); + RTS_SndLangData(ADV_SETTING_WIFI_TITLE_VP); + + RTS_SndLangData(MOTION_SETTING_TITLE_VP); + RTS_SndLangData(MOTION_SETTING_STEPSMM_TITLE_VP); + RTS_SndLangData(MOTION_SETTING_ACCEL_TITLE_VP); + RTS_SndLangData(MOTION_SETTING_JERK_TITLE_VP); + RTS_SndLangData(MOTION_SETTING_VELOCITY_TITLE_VP); + + RTS_SndLangData(MAX_VELOCITY_SETTING_TITLE_VP); + RTS_SndLangData(MAX_VELOCITY_XAXIS_TITLE_VP); + RTS_SndLangData(MAX_VELOCITY_YAXIS_TITLE_VP); + RTS_SndLangData(MAX_VELOCITY_ZAXIS_TITLE_VP); + RTS_SndLangData(MAX_VELOCITY_EAXIS_TITLE_VP); + + RTS_SndLangData(MAX_ACCEL_SETTING_TITLE_VP); + RTS_SndLangData(MAX_ACCEL_XAXIS_TITLE_VP); + RTS_SndLangData(MAX_ACCEL_YAXIS_TITLE_VP); + RTS_SndLangData(MAX_ACCEL_ZAXIS_TITLE_VP); + RTS_SndLangData(MAX_ACCEL_EAXIS_TITLE_VP); + + RTS_SndLangData(MAX_JERK_SETTING_TITLE_VP); + RTS_SndLangData(MAX_JERK_XAXIS_TITLE_VP); + RTS_SndLangData(MAX_JERK_YAXIS_TITLE_VP); + RTS_SndLangData(MAX_JERK_ZAXIS_TITLE_VP); + RTS_SndLangData(MAX_JERK_EAXIS_TITLE_VP); + + RTS_SndLangData(MAX_STEPSMM_SETTING_TITLE_VP); + RTS_SndLangData(MAX_STEPSMM_XAXIS_TITLE_VP); + RTS_SndLangData(MAX_STEPSMM_YAXIS_TITLE_VP); + RTS_SndLangData(MAX_STEPSMM_ZAXIS_TITLE_VP); + RTS_SndLangData(MAX_STEPSMM_EAXIS_TITLE_VP); + + RTS_SndLangData(TEMP_PID_SETTING_TITLE_VP); + RTS_SndLangData(NOZZLE_TEMP_P_TITLE_VP); + RTS_SndLangData(NOZZLE_TEMP_I_TITLE_VP); + RTS_SndLangData(NOZZLE_TEMP_D_TITLE_VP); + RTS_SndLangData(HOTBED_TEMP_P_TITLE_VP); + RTS_SndLangData(HOTBED_TEMP_I_TITLE_VP); + RTS_SndLangData(HOTBED_TEMP_D_TITLE_VP); + + RTS_SndLangData(FILAMENT_CONTROL_TITLE_VP); + RTS_SndLangData(POWERCONTINUE_CONTROL_TITLE_VP); + + RTS_SndLangData(MACHINE_TYPE_ABOUT_CHAR_VP); + RTS_SndLangData(FIRMWARE_VERSION_ABOUT_TEXT_VP); + RTS_SndLangData(PRINTER_DISPLAY_VERSION_TITLE_VP); + RTS_SndLangData(HARDWARE_VERSION_ABOUT_TITLE_VP); + RTS_SndLangData(WIFI_DN_CODE_CHAR_VP); + RTS_SndLangData(WEBSITE_ABOUT_CHAR_VP); + RTS_SndLangData(PRINTER_PRINTSIZE_TITLE_VP); + RTS_SndLangData(PLA_SETTINGS_TITLE_VP); + RTS_SndLangData(ABS_SETTINGS_TITLE_VP); + RTS_SndLangData(LEVELING_WAY_TITLE_VP); +} + +/** + * @brief Update the SD Card state, UI, etc. + * @details Called from marlin.idle() to manage the RTS UI + */ +void RTS_Update() { + // Check the status of card + if (!HMI_lcd_flag.home_flag && !G29_flag) // Cards are not detected during homing and leveling + rts.sdCardUpate(); + + rts.eachMomentUpdate(); + + // Wait to receive message and response + if (rts.receiveData() > 0) rts.handleData(); + if (!marlin.wait_for_heatup && !HMI_lcd_flag.home_flag && !G29_flag) Remove_card_window_check(); // rock_20220709 + hal.watchdog_refresh(); + + //AutoUIBedNozzleHeightCali(); // caixiaoliang 20210806 Call the nozzle platform height measurement function +} + +void RTS_PauseMoveAxisPage() { + if (waitway == 1) { + rts.sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + waitway = 0; + SERIAL_ECHOLNPGM("M79 S2"); // 2:cloud print pause + } + else if (waitway == 5) { + rts.sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + waitway = 0; + } + else if (waitway == 7) { + // Click stop print + rts.sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + waitway = 0; + } +} + +void RTS_AutoBedLevelPage() { + if (waitway == 3) { + rts.sendData(ui.language + 1, BEDLEVELING_WAIT_TITLE_VP); + rts.sendData(ExchangePageBase + 26, ExchangepageAddr); + change_page_font = 26; + waitway = 0; + } +} + +void RTS_MoveAxisHoming() { + if (waitway == 4) { + rts.sendData(ExchangePageBase + 16 + (AxisUnitMode - 1), ExchangepageAddr); + change_page_font = 16; + waitway = 0; + } + else if (waitway == 6) { + rts.sendData(ExchangePageBase + 25, ExchangepageAddr); + change_page_font = 25; + waitway = 0; + } + else if (waitway == 7) { + // Click Print finish + rts.sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + waitway = 0; + } + + RTS_UpdatePosition(); +} + +void RTS_CommandPause() { + if (printingIsActive()) { + rts.sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + // card.pauseSDPrint(); + // print_job_timer.pause(); + // pause_action_flag = true; + } +} + +void ErrorHanding() { + // No more operations + if (errorway == 1) { + errorway = errornum = 0; + } + else if (errorway == 2) { + // Z axis home failed + home_errornum++; + if (home_errornum <= 3) { + errorway = 0; + waitway = 4; + queue.enqueue_now(F("G28")); + rts.sendData(0, MOTOR_FREE_ICON_VP); + update_time_value = 0; + } + else { + // After three failed returns to home, it will report the failure interface + home_errornum = 0; + errorway = 0; + RTS_Error(Error_202); // Z axis home failed + + if (printingIsActive()) { + rts.sendData(0, PRINT_TIME_HOUR_VP); + rts.sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + + rts.sdCardStop(); + } + } + } + else if (errorway == 3) { + // No more operations + reset_bed_level(); + errorway = 0; + errornum = 0; + } + else if (errorway == 4) { + + } +} + +/** + * [调平步骤--开始找限位开关到CRTouch的距离] + * @Author Creality + * @Time 2021-09-22 + */ +bool RTS::levelStepHeightMeasure() { + #ifdef BLTOUCH + float coordinateOffset = VALUE_INVALID_8BIT; + // if (gLcdSermoonV2UI.GetStaGoingHome() != GO_HOME_DONE) return false; + + // set homing status - 'GO_HOME_IDLE' + // SetStaGoingHome(GO_HOME_IDLE); //此处用 home_flag 代替 + // bltouch+lower limit enabled + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + //constexpr xy_float_t test_offset_xy = {LEVEL_HEIGHT_MEASURE_X, LEVEL_HEIGHT_MEASURE_Y }; + //destination.set(test_offset_xy, current_position.z); + ////destination.set(safe_homing_xy, current_position.z); + //TERN_(1, destination -= probe.offset_xy); + //if (position_is_reachable(destination)) + // do_blocking_move_to_xy(destination); // Move bltouch to the middle + //else + // SERIAL_ECHO_MSG(STR_ZPROBE_OUT_SER); + //// The interface changes to "Operating" + //lcdDisplay.GotoScreen(DGUSLCD_SCREEN_MSG_OPERATE); + sendData(ExchangePageBase + 40, ExchangepageAddr); + // Start to measure the difference between two coordinates + //coordinateOffset = homeaxis_bl(Z_AXIS, Z_MEASURE_FEEDRATE_FAST, Z_MEASURE_FEEDRATE_SLOW); + if (coordinateOffset != VALUE_INVALID_8BIT) + setZCoordinateOffset(coordinateOffset); + else { + DEBUG_ECHOLNPGM(" coordinateOffset err!!! "); + //setZCoordinateOffset(0.0); + } + settings.save(); + #endif + + // After measuring the difference between the two coordinates, the + // nozzle moves to the detection point for height adjustment. + //MoveXYBlock(float(LEVEL_HEIGHT_MEASURE_X), float(LEVEL_HEIGHT_MEASURE_Y)); + + // Get to the base height, block + //MoveZBlock(0.0); + + // Show Z-axis compensation + sendData(probe.offset.z * 100, AUTO_BED_LEVEL_ZOFFSET_VP); + //sendData(probe.offset.z * 1000, VP_DATA_Z_OFFSET); + //uiShow.UI_ShowText(probe.offset.z, 3, lcdDisplay.current_screen, VP_DATA_Z_OFFSET); + #endif + + return true; +} + +void AutoUIBedNozzleHeightCali() { + if (st_bedNozzleHeightCal.bedNozzleHeightCalFinishFlag) return; + + switch (st_bedNozzleHeightCal.bedNozzleHeightState) { + case 0: + st_bedNozzleHeightCal.isBedLeveling = true; + st_bedNozzleHeightCal.goHomeSta = GO_HOME_IDLE; + queue.enqueue_now(F("M420 S0")); + #ifdef BLTOUCH + //queue.inject(F("G28")); + //queue.inject(F("G0 Z0")); + queue.enqueue_now(F("G28")); + //queue.enqueue_now(F("G0 Z0")); + #else + queue.inject(F("G29 S1")); + #endif + st_bedNozzleHeightCal.bedNozzleHeightState++; + break; + + case 1: + // wait for homing + if (st_bedNozzleHeightCal.goHomeSta == GO_HOME_DONE) { + // set homing status - 'GO_HOME_IDLE' + st_bedNozzleHeightCal.goHomeSta = GO_HOME_IDLE; + DEBUG_ECHOLNPGM("\n----------------------current_position.z!!!!!!= ", current_position.z * 100); + + // The coordinates at this point should be Z_MAX_POS + DEBUG_ECHOLN(current_position.z * 100); + destination.set(safe_homing_xy, current_position.z); + + destination -= probe.offset_xy; // TODO:OPTIONAL? + + if (position_is_reachable(destination)) { + // This causes the carriage on Dual X to unpark + TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false); + TERN_(SENSORLESS_HOMING, safe_delay(500)); // Short delay needed to settle + do_blocking_move_to_xy(destination); + } + else + DEBUG_ECHO_MSG(STR_ZPROBE_OUT_SER); + + homeaxis_bl(Z_AXIS); + + // Get to the center(x,y), block + LcdAutoUIMoveXYBlock(X_CENTER, Y_CENTER); + + // Get to the base height block + LcdAutoUIMoveZBlock(0.0f); + bedNozzleHeightCalZ = st_bedNozzleHeightCal.zCoordinateOffset; + settings.save(); // Call save data to save the measured height data + st_bedNozzleHeightCal.bedNozzleHeightState++; + } + break; + + case 2: + st_bedNozzleHeightCal.bedNozzleHeightState = 0; + st_bedNozzleHeightCal.bedNozzleHeightCalFinishFlag = true; + break; + + default: break; + } + + //if (st_bedNozzleHeightCal.bedNozzleHeightState == 2 && st_bedNozzleHeightCal.bedNozzleHeightCalFinishFlag) { + //// Probing is completed and the save button or return button is received + // st_bedNozzleHeightCal.bedNozzleHeightState=0; + // //DEBUG_ECHOPGM("\n..bedNozzleHeightCalFinish"); + //} +} + +/** + * [LcdAutoUIMoveXY :get to the given position(x, y), block program running] + * @Author Creality + * @Time 2021-06-08 + * @param _posX [X coordinate] + * @param _posY [Y coordinate] + */ +void LcdAutoUIMoveXYBlock(float _posX, float _posY) { + do_blocking_move_to_xy(_MIN(_posX, X_BED_SIZE), _MIN(_posY, Y_BED_SIZE)); +} + +/** + * [LcdAutoUIMoveZBlock :get to the given position(z), block program running] + * @Author Creality + * @Time 2021-06-08 + * @param _posZ [Z coordinate] + */ +void LcdAutoUIMoveZBlock(float _posZ) { + do_blocking_move_to_z(_MIN(_posZ, Z_MAX_POS)); +} + +/////////////////////// + +void RTS_Error(const char * const err) { + rts.sendData(ExchangePageBase + 41, ExchangepageAddr); + change_page_font = 41; + rts.sendText(err, ABNORMAL_PAGE_TEXT_VP); +} + +void RTS_OpenFileCloud() { + TERN_(FILAMENT_RUNOUT_SENSOR, if (runout.enabled) runout.filament_ran_out = false); + + if (PoweroffContinue) return; + + // clean print file + for (uint8_t i = 0; i < 20; ++i) rts.sendData(0, PRINT_FILE_TEXT_VP + i); + + char *cloudfilename = parser.string_arg; + int cloudnamelen = strlen(parser.string_arg); + int fileselect; + for (fileselect = 0; fileselect < CardRecbuf.Filesum; fileselect++) + if (0 == strncmp(CardRecbuf.Cardshowfilename[fileselect], cloudfilename, cloudnamelen)) break; + + int j = 1; + while (strncmp(&cloudfilename[j], ".gcode", 6) && strncmp(&cloudfilename[j], ".GCODE", 6) && j++ < cloudnamelen) { /* nada */ } + NOMORE(j, TEXTBYTELEN - 1); + strncpy(CardRecbuf.Cardshowfilename[fileselect], parser.string_arg, TEXTBYTELEN); + parser.string_arg[j] = '\0'; + + rts.sendData(CardRecbuf.Cardshowfilename[fileselect], PRINT_FILE_TEXT_VP); +} + +void RTS_PausedPrint() { + rts.sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + sdcard_pause_check = true; +} + +void RTS_PrintStartedSD() { + if (PoweroffContinue) return; + update_time_value = 0; + print_job_timer.start(); + rts.sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; +} + +void RTS_SDFileCompleted() { + PoweroffContinue = false; +} + +void RTS_UpdatePosition() { + rts.sendData(10 * current_position.x, AXIS_X_COORD_VP); + rts.sendData(10 * current_position.y, AXIS_Y_COORD_VP); + rts.sendData(10 * current_position.z, AXIS_Z_COORD_VP); +} + +void RTS_UpdateFeedrate(const int16_t frp) { + rts.sendData(frp, PRINT_SPEED_RATE_VP); + DEBUG_ECHOLNPGM("M220 S", frp); +} + +void RTS_UpdateWifi() { + rts.sendData(wifi_enable_flag ? 0 : 1, ADV_SETTING_WIFI_ICON_VP); + rts.sendData(wifi_enable_flag ? 1 : 0, WIFI_CONNECTED_DISPLAY_ICON_VP); +} + +void RTS_StepperTimeout() { + waitway = 0; + RTS_Error(Error_201); + errorway = 1; +} + +void RTS_ReheatHotend(const celsius_t c/*=170*/) { + if (thermalManager.degTargetHotend(0) > 0) temphot = thermalManager.degTargetHotend(0); + thermalManager.setTargetHotend(c, 0); + rts.sendData(c, HEAD_SET_TEMP_VP); +} + +void RTS_FilamentRanOut() { + temphot = thermalManager.degTargetHotend(0); + rts.sendData(ExchangePageBase + 7, ExchangepageAddr); + change_page_font = 7; + sdcard_pause_check = true; +} + +void RTS_FileHasFinished() { + rts.sendData(100, PRINT_PROCESS_VP); delay(1); + rts.sendData(100, PRINT_PROCESS_ICON_VP); delay(1); + rts.sendData(ExchangePageBase + 9, ExchangepageAddr); + DEBUG_ECHOLNPGM("M79 S5"); // 5:cloud print complete +} + +void RTS_ProbingPauseHotend() { + #if ENABLED(PROBING_HEATERS_OFF) + if (thermalManager.degTargetHotend(0) > 0) { + temphot = thermalManager.degTargetHotend(0); + thermalManager.setTargetHotend(0, 0); + rts.sendData(0, HEAD_SET_TEMP_VP); + } + #endif +} + +void RTS_ProbingPauseFans() { + #if ENABLED(PROBING_FANS_OFF) + afterprobe_fan0_speed = thermalManager.fan_speed[0]; + if (thermalManager.fan_speed[0] > 0) { + thermalManager.set_fan_speed(0, 0); + rts.sendData(0, PRINTER_FANOPEN_TITLE_VP); + } + #endif +} + +void RTS_ProbingResumeHotend() { + #if ENABLED(PROBING_HEATERS_OFF) + if (temphot > 0 && card.isPrinting()) { + rts.sendData(temphot, HEAD_SET_TEMP_VP); + thermalManager.setTargetHotend(temphot, 0); + if (temphot > thermalManager.degHotend(0) - 5) thermalManager.wait_for_hotend(false); + while (thermalManager.still_heating(0)) marlin.idle(); + } + #endif +} + +void RTS_ProbingResumeFans() { + #if ENABLED(PROBING_FANS_OFF) + if (afterprobe_fan0_speed > 0 && card.isPrinting()) { + thermalManager.set_fan_speed(0, afterprobe_fan0_speed); + rts.sendData(1, PRINTER_FANOPEN_TITLE_VP); + } + #endif +} + +void RTS_LevelingUpdate(uint8_t &count, const uint8_t total) { + if (card.isStillPrinting()) return; + if (count >= total) return; + count++; + rts.sendData(count * 50 / total, AUTO_BED_LEVEL_TITLE_VP); + rts.sendData(count * 100 / total, AUTO_LEVELING_PERCENT_DATA_VP); + rts.sendData(thermalManager.degHotend(0), HEAD_CURRENT_TEMP_VP); + rts.sendData(ExchangePageBase + 26, ExchangepageAddr); + change_page_font = 26; + // TODO: Send the Z value from the in-progress leveling + //rts.sendData(bedlevel.z_values[meshCount.x][meshCount.y]*1000, AUTO_BED_LEVEL_1POINT_VP + (count - 1) * 2); +} + +void RTS_LevelingDone() { + G29_flag = false; + //G29_finished = true; // G29 has been completed rock_20220902 + RTS_AutoBedLevelPage(); +} + +void RTS_ProbingFailed() { + waitway = 0; + RTS_Error(Error_203); + errorway = 3; +} + +// Cloud Print Status Flags +int32_t g_couldPrintState = COULD_PRINT_STATE_OFF; + +void RTS_CloudCommand(const cloudCommand_t cloud_cmd) { + switch (cloud_cmd) { + case 0: + // 0:cloud connect + rts.sendData(1, WIFI_CONNECTED_DISPLAY_ICON_VP); + break; + + case 1: + // 1:cloud print start + if (!PoweroffContinue) { + update_time_value = 0; + print_job_timer.start(); + rts.sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + g_couldPrintState = COULD_PRINT_STATE_RUNNING; + } + break; + + case 2: + // 2:cloud print pause + if (!PoweroffContinue) { // Cloud printing + update_time_value = 0; + print_job_timer.pause(); + if (!runout.filament_ran_out) { + rts.sendData(ExchangePageBase + 12, ExchangepageAddr); + change_page_font = 12; + } + g_couldPrintState = COULD_PRINT_STATE_PAUSE; + } + else if (PoweroffContinue) { // Print locally + if (!marlin.wait_for_heatup) { // No hydronic heating + rts.sendData(ExchangePageBase + 40, ExchangepageAddr); + waitway = 1; + pause_e = current_position.e - 3; + if (!temphot) temphot = thermalManager.temp_hotend[0].target; + card.pauseSDPrint(); + print_job_timer.pause(); + pause_action_flag = true; + update_time_value = 0; + planner.synchronize(); + sdcard_pause_check = false; + } + else { // If it is heating in circulation, it will continue to print + SERIAL_ECHOLNPGM("M79 S3"); + break; + } + } + break; + + case 3: + // 3: Cloud print resume + if (!PoweroffContinue) { // Cloud printing + update_time_value = 0; + print_job_timer.start(); + rts.sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + if (g_cloudPLRStatusValue == CLOUD_PLR_CHOOSE_STATE) // There is a power failure to continue playing + g_cloudPLRStatusValue = CLOUD_PLR_YES_STATE; + g_couldPrintState = COULD_PRINT_STATE_RUNNING; + } + else if (PoweroffContinue) { // Print locally + if (CardReader::flag.mounted) { + if (CLOUD_PLR_NULL_STATE == g_cloudPLRStatusValue) { // Continuous play without power failure + rts.sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + #if ENABLED(HAS_RESUME_CONTINUE) + const bool was_wait = marlin.wait_for_user; + marlin.wait_for_user = false; + #else + constexpr bool was_wait = false; + #endif + if (!was_wait) { + memset(commandbuf, 0, sizeof(commandbuf)); + sprintf_P(commandbuf, PSTR("M109 S%i"), temphot); + queue.enqueue_one_now(commandbuf); + + card.startOrResumeFilePrinting(); + print_job_timer.start(); + update_time_value = 0; + sdcard_pause_check = true; + } + } + else if (g_cloudPLRStatusValue == CLOUD_PLR_CHOOSE_STATE) { // 有断电续打 + g_cloudPLRStatusValue = CLOUD_PLR_YES_STATE; + PoweroffContinue = true; + power_off_type_yes = true; + update_time_value = 0; + rts.sendData(ExchangePageBase + 10, ExchangepageAddr); + change_page_font = 10; + // recovery.resume(); + queue.enqueue_now(F("M1000")); + sdcard_pause_check = true; + rts.sendData(feedrate_percentage, PRINT_SPEED_RATE_VP); + } + } + } + break; + + case 4: + // 4:cloud print stop + if (!PoweroffContinue) { + update_time_value = 0; + rts.sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + rts.sendData(0, PRINT_PROCESS_VP); + rts.sendData(0, PRINT_PROCESS_ICON_VP); + print_job_timer.stop(); + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + } + else if (PoweroffContinue) { + if (27 == change_page_font) { // 有本地断电续打 + update_time_value = RTS_UPDATE_VALUE; + rts.sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + rts.sendData(0, PRINT_TIME_HOUR_VP); + rts.sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + rts.sdCardStop(); + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + break; + } + rts.sendData(0, PRINT_TIME_HOUR_VP); + rts.sendData(0, PRINT_TIME_MIN_VP); + update_time_value = 0; + temphot = 0; + rts.sendData(ExchangePageBase + 40, ExchangepageAddr); + waitway = 7; + rts.sdCardStop(); + gcode.process_subcommands_now(F("G28 XY\nM84")); + g_cloudPLRStatusValue = CLOUD_PLR_NULL_STATE; + } + break; + + case 5: + // 5:cloud print complete + if (!PoweroffContinue) { + update_time_value = 0; + print_job_timer.stop(); + rts.sendData(ExchangePageBase + 1, ExchangepageAddr); + change_page_font = 1; + rts.sendData(0, PRINT_PROCESS_VP); + rts.sendData(0, PRINT_PROCESS_ICON_VP); + } + break; + + case 6: + // 6:cloud print power continue + if (!PoweroffContinue) { + rts.sendData(ExchangePageBase + 27, ExchangepageAddr); + change_page_font = 27; + power_off_type_yes = true; + g_cloudPLRStatusValue = CLOUD_PLR_CHOOSE_STATE; + } + break; + + default: break; + } +} + +void RTS_SetStatsFR(const feedRate_t fr_mm_s) { + rts.sendData(fr_mm_s, PRINT_PROCESS_VP); + rts.sendData(fr_mm_s, PRINT_PROCESS_ICON_VP); +} + +void RTS_SetStatsTime(const millis_t time) { + rts.sendData(time / 3600, PRINT_TIME_HOUR_VP); + rts.sendData((time % 3600) / 60, PRINT_TIME_MIN_VP); +} + +void RTS_SetStatsRemain(const millis_t remain) { + rts.sendData(remain / 3600, PRINT_REMAIN_TIME_HOUR_VP); + rts.sendData((remain % 3600) / 60, PRINT_REMAIN_TIME_MIN_VP); +} + +void RTS_SetLED(const bool on) { + rts.sendData(on ? 0 : 1, PRINTER_LEDOPEN_TITLE_VP); + #if PIN_EXISTS(LED_CONTROL) + WRITE(LED_CONTROL_PIN, on ? HIGH : LOW); + #endif +} + +#endif // CREALITY_RTS diff --git a/Marlin/src/lcd/rts/lcd_rts.h b/Marlin/src/lcd/rts/lcd_rts.h new file mode 100755 index 0000000000..bf76f265c9 --- /dev/null +++ b/Marlin/src/lcd/rts/lcd_rts.h @@ -0,0 +1,701 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Resistive Touch Screen + * Copyright (c) 2023 Creality3D + */ +#include "../../inc/MarlinConfig.h" + +extern bool power_off_type_yes; + +/*********************************/ +#define FHONE (0x5A) +#define FHTWO (0xA5) +#define FHLENG (0x06) +#define TEXTBYTELEN 20 +#define MaxFileNumber 20 + +#define VALUE_INVALID 0xFFFF +#define VALUE_INVALID_8BIT 0xFF + +#define AUTO_BED_LEVEL_PREHEAT 120 + +#define FileNum MaxFileNumber +#define FileNameLen TEXTBYTELEN +#define RTS_UPDATE_INTERVAL 2000 +#define RTS_UPDATE_VALUE RTS_UPDATE_INTERVAL + +#define RTS_DATA_SIZE 26 + +/*************Register and Variable addr*****************/ +#define RegAddr_W 0x80 +#define RegAddr_R 0x81 +#define VarAddr_W 0x82 +#define VarAddr_R 0x83 +#define ExchangePageBase ((unsigned long)0x5A010000) +#define StartSoundSet ((unsigned long)0x060480A0) + +/*Error value*/ +#define Error_06 "E06" // Nozzle heat escape +#define Error_07 "E07" // Nozzle heating failed +#define Error_08 "E08" // Nozzle thermal abnormality +#define Error_09 "E09" // Bed heat escape +#define Error_10 "E10" // Bed heating failed +#define Error_11 "E11" // Bed thermal abnormality + +#define Error_201 "E201" // The command too much inactive time +#define Error_202 "E202" // Homing Failed +#define Error_203 "E203" // Probing Failed +#define Error_204 "E204" // SD Read Error +#define Error_205 "OTA update mainboard wait 180s" // OTA update mainboard wait 180s +#define Error_206 "OTA update screen wait 2400s" // OTA update touch screen wait 2400s + +/*variable addr*/ +#define ExchangepageAddr 0x0084 +#define SoundAddr 0x00A0 + +#define START_PROCESS_ICON_VP 0x1000 +#define PRINT_SPEED_RATE_VP 0x1006 +#define PRINT_PROCESS_ICON_VP 0x100E +#define PRINT_TIME_HOUR_VP 0x1010 +#define PRINT_TIME_MIN_VP 0x1012 +#define PRINT_PROCESS_VP 0x1016 +#define PRINTER_FANOPEN_TITLE_VP 0x101E +#define PRINTER_LEDOPEN_TITLE_VP 0x101F +//#define PRINTER_AUTO_SHUTDOWN_ICON_VP 0x1020 +#define ADV_SETTING_WIFI_ICON_VP 0x1021 +#define AUTO_BED_LEVEL_ZOFFSET_VP 0x1026 + +#define HEAD_SET_TEMP_VP 0x1034 +#define HEAD_CURRENT_TEMP_VP 0x1036 +#define BED_SET_TEMP_VP 0x103A +#define BED_CURRENT_TEMP_VP 0x103C +#define AXIS_X_COORD_VP 0x1048 +#define AXIS_Y_COORD_VP 0x104A +#define AXIS_Z_COORD_VP 0x104C +#define HEAD_FILAMENT_LOAD_DATA_VP 0x1052 +#define HEAD_FILAMENT_UNLOAD_DATA_VP 0x1054 +#define AUTO_BED_PREHEAT_HEAD_DATA_VP 0x108A +#define AUTO_BED_LEVEL_TITLE_VP 0x108D +#define FILAMENT_LOAD_ICON_VP 0x108E +#define PREHEAT_PLA_SET_NOZZLE_TEMP_VP 0x1090 +#define PREHEAT_PLA_SET_BED_TEMP_VP 0x1092 +#define PREHEAT_ABS_SET_NOZZLE_TEMP_VP 0x1094 +#define PREHEAT_ABS_SET_BED_TEMP_VP 0x1096 +#define FAN_SPEED_CONTROL_DATA_VP 0x109A +#define AUTO_LEVELING_PERCENT_DATA_VP 0x109C + +#define MAX_VELOCITY_XAXIS_DATA_VP 0x109E +#define MAX_VELOCITY_YAXIS_DATA_VP 0x10A0 +#define MAX_VELOCITY_ZAXIS_DATA_VP 0x10A2 +#define MAX_VELOCITY_EAXIS_DATA_VP 0x10A4 + +#define MAX_ACCEL_XAXIS_DATA_VP 0x10A6 +#define MAX_ACCEL_YAXIS_DATA_VP 0x10A8 +#define MAX_ACCEL_ZAXIS_DATA_VP 0x10AA +#define MAX_ACCEL_EAXIS_DATA_VP 0x10AC + +#define MAX_JERK_XAXIS_DATA_VP 0x10AE +#define MAX_JERK_YAXIS_DATA_VP 0x10B0 +#define MAX_JERK_ZAXIS_DATA_VP 0x10B2 +#define MAX_JERK_EAXIS_DATA_VP 0x10B4 + +#define MAX_STEPSMM_XAXIS_DATA_VP 0x10B6 +#define MAX_STEPSMM_YAXIS_DATA_VP 0x10B8 +#define MAX_STEPSMM_ZAXIS_DATA_VP 0x10BA +#define MAX_STEPSMM_EAXIS_DATA_VP 0x10BC + +#define NOZZLE_TEMP_P_DATA_VP 0x10BE +#define NOZZLE_TEMP_I_DATA_VP 0x10C0 +#define NOZZLE_TEMP_D_DATA_VP 0x10C2 +#define HOTBED_TEMP_P_DATA_VP 0x10C4 +#define HOTBED_TEMP_I_DATA_VP 0x10C6 +#define HOTBED_TEMP_D_DATA_VP 0x10C8 + +#define PRINT_CURRENT_PAGE_DATA_VP 0x10CA +#define PRINT_COUNT_PAGE_DATA_VP 0x10CC +#define WIFI_CONNECTED_DISPLAY_ICON_VP 0x10CE +#define WIFI_RESET_REMAIN_TIME_DATA_VP 0x10D0 +#define PRINT_REMAIN_TIME_HOUR_VP 0x10D2 +#define PRINT_REMAIN_TIME_MIN_VP 0x10D4 + +#define AUTO_BED_LEVEL_1POINT_VP 0x1100 +#define AUTO_BED_LEVEL_2POINT_VP 0x1102 +#define AUTO_BED_LEVEL_3POINT_VP 0x1104 +#define AUTO_BED_LEVEL_4POINT_VP 0x1106 +#define AUTO_BED_LEVEL_5POINT_VP 0x1108 +#define AUTO_BED_LEVEL_6POINT_VP 0x110A +#define AUTO_BED_LEVEL_7POINT_VP 0x110C +#define AUTO_BED_LEVEL_8POINT_VP 0x110E +#define AUTO_BED_LEVEL_9POINT_VP 0x1110 +#define AUTO_BED_LEVEL_10POINT_VP 0x1112 +#define AUTO_BED_LEVEL_11POINT_VP 0x1114 +#define AUTO_BED_LEVEL_12POINT_VP 0x1116 +#define AUTO_BED_LEVEL_13POINT_VP 0x1118 +#define AUTO_BED_LEVEL_14POINT_VP 0x111A +#define AUTO_BED_LEVEL_15POINT_VP 0x111C +#define AUTO_BED_LEVEL_16POINT_VP 0x111E +#define AUTO_BED_LEVEL_17POINT_VP 0x110E +#define AUTO_BED_LEVEL_18POINT_VP 0x1110 +#define AUTO_BED_LEVEL_19POINT_VP 0x1112 +#define AUTO_BED_LEVEL_20POINT_VP 0x1114 +#define AUTO_BED_LEVEL_21POINT_VP 0x1116 +#define AUTO_BED_LEVEL_22POINT_VP 0x1118 +#define AUTO_BED_LEVEL_23POINT_VP 0x111A +#define AUTO_BED_LEVEL_24POINT_VP 0x111C +#define AUTO_BED_LEVEL_25POINT_VP 0x111E + +#define CHANGE_SDCARD_ICON_VP 0x1168 +#define MOVEAXIS_UNIT_ICON_VP 0x116A +#define PREHAEAT_NOZZLE_ICON_VP 0x116B +#define PREHAEAT_HOTBED_ICON_VP 0x116C +#define FILAMENT_CONTROL_ICON_VP 0x116D +#define POWERCONTINUE_CONTROL_ICON_VP 0x116E + +#define MOTOR_FREE_ICON_VP 0x1200 +#define FILE1_SELECT_ICON_VP 0x1221 +#define FILE2_SELECT_ICON_VP 0x1222 +#define FILE3_SELECT_ICON_VP 0x1223 +#define FILE4_SELECT_ICON_VP 0x1224 +#define FILE5_SELECT_ICON_VP 0x1225 +#define FILE6_SELECT_ICON_VP 0x1226 +#define FILE7_SELECT_ICON_VP 0x1227 +#define FILE8_SELECT_ICON_VP 0x1228 +#define FILE9_SELECT_ICON_VP 0x1229 +#define FILE10_SELECT_ICON_VP 0x122A +#define FILE11_SELECT_ICON_VP 0x122B +#define FILE12_SELECT_ICON_VP 0x122C +#define FILE13_SELECT_ICON_VP 0x122D +#define FILE14_SELECT_ICON_VP 0x122E +#define FILE15_SELECT_ICON_VP 0x122F +#define FILE16_SELECT_ICON_VP 0x1230 +#define FILE17_SELECT_ICON_VP 0x1231 +#define FILE18_SELECT_ICON_VP 0x1232 +#define FILE19_SELECT_ICON_VP 0x1233 +#define FILE20_SELECT_ICON_VP 0x1234 + +#define FILE1_TEXT_VP 0x200A +#define FILE2_TEXT_VP 0x201E +#define FILE3_TEXT_VP 0x2032 +#define FILE4_TEXT_VP 0x2046 +#define FILE5_TEXT_VP 0x205A +#define FILE6_TEXT_VP 0x206E +#define FILE7_TEXT_VP 0x2082 +#define FILE8_TEXT_VP 0x2096 +#define FILE9_TEXT_VP 0x20AA +#define FILE10_TEXT_VP 0x20BE +#define FILE11_TEXT_VP 0x20D2 +#define FILE12_TEXT_VP 0x20E6 +#define FILE13_TEXT_VP 0x20FA +#define FILE14_TEXT_VP 0x210E +#define FILE15_TEXT_VP 0x2122 +#define FILE16_TEXT_VP 0x2136 +#define FILE17_TEXT_VP 0x214A +#define FILE18_TEXT_VP 0x215E +#define FILE19_TEXT_VP 0x2172 +#define FILE20_TEXT_VP 0x2186 + +#define SELECT_FILE_TEXT_VP 0x219A +#define PRINT_FILE_TEXT_VP 0x21C0 +#define ABNORMAL_PAGE_TEXT_VP 0x21D4 + +#define MAIN_PAGE_BLUE_TITLE_VP 0x1300 +#define SELECT_FILE_BLUE_TITLE_VP 0x1301 +#define PREPARE_PAGE_BLUE_TITLE_VP 0x1302 +#define SETTING_PAGE_BLUE_TITLE_VP 0x1303 +#define MAIN_PAGE_BLACK_TITLE_VP 0x1304 +#define SELECT_FILE_BLACK_TITLE_VP 0x1305 +#define PREPARE_PAGE_BLACK_TITLE_VP 0x1306 +#define SETTING_PAGE_BLACK_TITLE_VP 0x1307 + +#define PRINT_ADJUST_MENT_TITLE_VP 0x130D +#define PRINT_SPEED_TITLE_VP 0x130E +#define HEAD_SET_TITLE_VP 0x130F +#define BED_SET_TITLE_VP 0x1310 +#define LEVEL_ZOFFSET_TITLE_VP 0x1311 +#define FAN_CONTROL_TITLE_VP 0x1312 +#define LED_CONTROL_TITLE_VP 0x1313 + +#define MOVE_AXIS_ENTER_GREY_TITLE_VP 0x1314 +#define CHANGE_FILAMENT_GREY_TITLE_VP 0x1315 +#define PREHEAT_PAGE_GREY_TITLE_VP 0x1316 +#define MOVE_AXIS_ENTER_BLACK_TITLE_VP 0x1317 +#define CHANGE_FILAMENT_BLACK_TITLE_VP 0x1318 +#define PREHEAT_PAGE_BLACK_TITLE_VP 0x1319 + +#define PREHEAT_PLA_BUTTON_TITLE_VP 0x131A +#define PREHEAT_ABS_BUTTON_TITLE_VP 0x131B +#define COOL_DOWN_BUTTON_TITLE_VP 0x131C + +#define FILAMENT_LOAD_BUTTON_TITLE_VP 0x1321 +#define FILAMENT_UNLOAD_BUTTON_TITLE_VP 0x1322 + +#define LANGUAGE_SELECT_ENTER_VP 0x1323 +#define FACTORY_DEFAULT_ENTER_TITLE_VP 0x1324 +#define LEVELING_PAGE_TITLE_VP 0x1325 + +#define PRINTER_DEVICE_GREY_TITLE_VP 0x1326 +#define PRINTER_ADVINFO_GREY_TITLE_VP 0x1327 +#define PRINTER_INFO_ENTER_GREY_TITLE_VP 0x1328 +#define PRINTER_DEVICE_BLACK_TITLE_VP 0x1329 +#define PRINTER_ADVINFO_BLACK_TITLE_VP 0x132A +#define PRINTER_INFO_ENTER_BLACK_TITLE_VP 0x132B + +#define PREHEAT_PLA_SET_TITLE_VP 0x132D +#define PREHEAT_ABS_SET_TITLE_VP 0x132E + +#define STORE_MEMORY_CONFIRM_TITLE_VP 0x1332 +#define STORE_MEMORY_CANCEL_TITLE_VP 0x1333 + +#define FILAMENT_UNLOAD_IGNORE_TITLE_VP 0x133E +#define FILAMENT_USEUP_TITLE_VP 0x133F +#define BUTTON_CHECK_CONFIRM_TITLE_VP 0x1340 +#define BUTTON_CHECK_CANCEL_TITLE_VP 0x1341 +#define FILAMENT_LOAD_TITLE_VP 0x1342 +#define FILAMENT_LOAD_RESUME_TITLE_VP 0x1343 +#define PAUSE_PRINT_POP_TITLE_VP 0x1344 +#define STOP_PRINT_POP_TITLE_VP 0x1347 +#define POWERCONTINUE_POP_TITLE_VP 0x1348 +#define AUTO_HOME_WAITING_POP_TITLE_VP 0x1349 + +#define BEDLEVELING_WAIT_TITLE_VP 0x134B +#define RESTORE_FACTORY_TITLE_VP 0x134D +#define RESET_WIFI_SETTING_TITLE_VP 0x134E +#define KILL_THERMAL_RUNAWAY_TITLE_VP 0x134F +#define KILL_HEATING_FAIL_TITLE_VP 0x1350 +#define KILL_THERMISTOR_ERROR_TITLE_VP 0x1351 +#define WIND_AUTO_SHUTDOWN_TITLE_VP 0x1352 +#define RESET_WIFI_SETTING_BUTTON_VP 0x1353 +#define PRINTER_AUTO_SHUTDOWN_TITLE_VP 0x1354 +#define WIND_AUTO_SHUTDOWN_PAGE_VP 0x1355 +#define AUTO_LEVELING_START_TITLE_VP 0x1356 +#define AUX_LEVELING_GREY_TITLE_VP 0x1357 +#define AUTO_LEVELING_GREY_TITLE_VP 0x1358 +#define AUX_LEVELING_BLACK_TITLE_VP 0x1359 +#define AUTO_LEVELING_BLACK_TITLE_VP 0x135A +#define LANGUAGE_SELECT_PAGE_TITLE_VP 0x135B +#define ADV_SETTING_MOTION_TITLE_VP 0x135C +#define ADV_SETTING_PID_TITLE_VP 0x135D +#define ADV_SETTING_WIFI_TITLE_VP 0x135E + +#define MOTION_SETTING_TITLE_VP 0x135F +#define MOTION_SETTING_STEPSMM_TITLE_VP 0x1360 +#define MOTION_SETTING_ACCEL_TITLE_VP 0x1361 +#define MOTION_SETTING_JERK_TITLE_VP 0x1362 +#define MOTION_SETTING_VELOCITY_TITLE_VP 0x1363 + +#define MAX_VELOCITY_SETTING_TITLE_VP 0x1364 +#define MAX_VELOCITY_XAXIS_TITLE_VP 0x1365 +#define MAX_VELOCITY_YAXIS_TITLE_VP 0x1366 +#define MAX_VELOCITY_ZAXIS_TITLE_VP 0x1367 +#define MAX_VELOCITY_EAXIS_TITLE_VP 0x1368 + +#define MAX_ACCEL_SETTING_TITLE_VP 0x1369 +#define MAX_ACCEL_XAXIS_TITLE_VP 0x136A +#define MAX_ACCEL_YAXIS_TITLE_VP 0x136B +#define MAX_ACCEL_ZAXIS_TITLE_VP 0x136C +#define MAX_ACCEL_EAXIS_TITLE_VP 0x136D + +#define MAX_JERK_SETTING_TITLE_VP 0x136E +#define MAX_JERK_XAXIS_TITLE_VP 0x136F +#define MAX_JERK_YAXIS_TITLE_VP 0x1370 +#define MAX_JERK_ZAXIS_TITLE_VP 0x1371 +#define MAX_JERK_EAXIS_TITLE_VP 0x1372 + +#define MAX_STEPSMM_SETTING_TITLE_VP 0x1373 +#define MAX_STEPSMM_XAXIS_TITLE_VP 0x1374 +#define MAX_STEPSMM_YAXIS_TITLE_VP 0x1375 +#define MAX_STEPSMM_ZAXIS_TITLE_VP 0x1376 +#define MAX_STEPSMM_EAXIS_TITLE_VP 0x1377 + +#define TEMP_PID_SETTING_TITLE_VP 0x1378 +#define NOZZLE_TEMP_P_TITLE_VP 0x1379 +#define NOZZLE_TEMP_I_TITLE_VP 0x137A +#define NOZZLE_TEMP_D_TITLE_VP 0x137B +#define HOTBED_TEMP_P_TITLE_VP 0x137C +#define HOTBED_TEMP_I_TITLE_VP 0x137D +#define HOTBED_TEMP_D_TITLE_VP 0x137E + +#define FILAMENT_CONTROL_TITLE_VP 0x137F +#define POWERCONTINUE_CONTROL_TITLE_VP 0x1380 + +#define PLA_SETTINGS_TITLE_VP 0x1382 //新增PLA设置词条 +#define ABS_SETTINGS_TITLE_VP 0x1384 //新增ABS设置词条 + +#define LEVELING_WAY_TITLE_VP 0x1386 //新增调平方式侧跳 + +#define MACHINE_TYPE_ABOUT_CHAR_VP 0x1400 +#define FIRMWARE_VERSION_ABOUT_CHAR_VP 0x1401 +#define PRINTER_DISPLAY_VERSION_TITLE_VP 0x1402 +#define HARDWARE_VERSION_ABOUT_TITLE_VP 0x1403 +#define WIFI_DN_CODE_CHAR_VP 0x1404 +#define WEBSITE_ABOUT_CHAR_VP 0x1405 +#define PRINTER_PRINTSIZE_TITLE_VP 0x1406 + +#define LANGUAGE_CHINESE_TITLE_VP 0x1411 +#define LANGUAGE_ENGLISH_TITLE_VP 0x1412 +#define LANGUAGE_GERMAN_TITLE_VP 0x1413 +#define LANGUAGE_SPANISH_TITLE_VP 0x1414 +#define LANGUAGE_FRENCH_TITLE_VP 0x1415 +#define LANGUAGE_ITALIAN_TITLE_VP 0x1416 +#define LANGUAGE_PORTUGUESE_TITLE_VP 0x1417 +#define LANGUAGE_RUSSIAN_TITLE_VP 0x1418 +#define LANGUAGE_TURKISH_TITLE_VP 0x1419 + +#define MACHINE_NAME_ABOUT_TEXT_VP 0x17B0 +#define FIRMWARE_VERSION_ABOUT_TEXT_VP 0x17C4 +#define PRINTER_DISPLAY_VERSION_TEXT_VP 0x17D8 +#define HARDWARE_VERSION_ABOUT_TEXT_VP 0x17EC +#define PRINTER_PRINTSIZE_TEXT_VP 0x1800 +#define WEBSITE_ABOUT_TEXT_VP 0x1814 + +#define FilenameNature 0x6003 + +#define LCD_LED_CONFIG_REGISTER 0x0082 +#define LCD_TP_STATUS_REGISTER 0x0016 +#define LCD_SHUTDOWN_LIGHT_LEVEL 0x0A +#define LCD_OPEN_LIGHT_LEVEL 0x64 + +#define TIME_PRINT_OVER_SHUTDOWN 300 +#define TIME_WIFI_RESET_BACKPAGE 60 + +#define ABNORMAL_PAGE_TEXT_VP_SIZE 30 + +/************struct**************/ + +typedef struct DataBuf { + unsigned char len; + unsigned char head[2]; + unsigned char command; + unsigned long addr; + unsigned long bytelen; + unsigned short data[32]; + unsigned char reserv[4]; +} DB; + +typedef struct CardRecord { + int recordcount; + int Filesum; + unsigned long addr[FileNum]; + char Cardshowfilename[FileNum][FileNameLen]; + char Cardfilename[FileNum][FileNameLen]; + bool selectFlag; +} CRec; + +extern CRec CardRecbuf; + +typedef struct { + bool pause_flag:1; + bool pause_action:1; + bool print_finish:1; + bool done_confirm_flag:1; + bool select_flag:1; + bool home_flag:1; + bool heat_flag:1; // 0: heating done 1: during heating + bool remove_card_flag:1; +} HMI_LCD_Flag_t; + +extern HMI_LCD_Flag_t HMI_lcd_flag; + +class RTS { + public: + RTS(); + + static float zCoordinateOffset; // Z-axis space coordinate difference + + // Leveling-related functions + static bool levelStepHeightMeasure(); + + static void setZCoordinateOffset(const float _offset) { // Set the difference between the two coordinates + zCoordinateOffset = _offset; // (the lower limit of Z and the coordinate system established by BLTouch) + } + + static void eachMomentUpdate(); + + static int receiveData(); + static void sdCardInit(); + static bool sdDetected(); + static void sdCardUpate(); + static void updateLanguageDisplay(); + static void sendData(); + //static void sendData(const String &, unsigned long, unsigned char=VarAddr_W); + static void sendData(const char[], unsigned long, unsigned char=VarAddr_W); + static void sendData(char, unsigned long, unsigned char=VarAddr_W); + static void sendData(unsigned char*, unsigned long, unsigned char=VarAddr_W); + static void sendData(int, unsigned long, unsigned char=VarAddr_W); + static void sendData(float, unsigned long, unsigned char=VarAddr_W); + static void sendData(unsigned int, unsigned long, unsigned char=VarAddr_W); + static void sendData(long, unsigned long, unsigned char=VarAddr_W); + static void sendData(unsigned long, unsigned long, unsigned char=VarAddr_W); + static void sdCardStop(); + static void handleData(); + static void init(); + static void sendText(const char string[], unsigned long addr, uint8_t textSize=30); + static DB recdat; + static DB snddat; + private: + static unsigned char databuf[RTS_DATA_SIZE]; +}; + +extern RTS rts; + +/******* Definitions related to leveling (beginning) ********/ + +#define Z_MEASURE_PLANTFORM 10 // When measuring the platform, the height of the z-axis lift +#define Z_MEASURE_FEEDRATE_FAST Z_PROBE_FEEDRATE_FAST*4 // Detect maximum speed +#define Z_MEASURE_FEEDRATE_SLOW Z_PROBE_FEEDRATE_SLOW // Probe minimum speed + +#if ENABLED(MENU_RESET_WIFI) + typedef enum : uint8_t { INITIAL = 0, PRESSED, RECORDTIME } wifi_state_t; + extern wifi_state_t rts_wifi_state; +#endif + +typedef enum PROC_COM : int8_t { + NoKey = -1, + MainEnterKey = 0, + AdjustEnterKey = 1, + PrintSpeedEnterKey = 2, + StopPrintKey = 3, + PausePrintKey = 4, + ResumePrintKey = 5, + ZoffsetEnterKey = 6, + TempControlKey = 7, + CoolDownKey = 8, + HeaterTempEnterKey = 9, + HotBedTempEnterKey = 10, + PrepareEnterKey = 11, + BedLevelKey = 12, + AutoHomeKey = 13, + XaxismoveKey = 14, + YaxismoveKey = 15, + ZaxismoveKey = 16, + HeaterLoadEnterKey = 17, + HeaterUnLoadEnterKey = 18, + HeaterLoadStartKey = 19, + SelectLanguageKey = 20, + PowerContinuePrintKey = 21, + PLAHeadSetEnterKey = 22, + PLABedSetEnterKey = 23, + ABSHeadSetEnterKey = 24, + ABSBedSetEnterKey = 25, + StoreMemoryKey = 26, + FanSpeedEnterKey = 27, + VelocityXaxisEnterKey = 28, + VelocityYaxisEnterKey = 29, + VelocityZaxisEnterKey = 30, + VelocityEaxisEnterKey = 31, + AccelXaxisEnterKey = 32, + AccelYaxisEnterKey = 33, + AccelZaxisEnterKey = 34, + AccelEaxisEnterKey = 35, + JerkXaxisEnterKey = 36, + JerkYaxisEnterKey = 37, + JerkZaxisEnterKey = 38, + JerkEaxisEnterKey = 39, + StepsmmXaxisEnterKey = 40, + StepsmmYaxisEnterKey = 41, + StepsmmZaxisEnterKey = 42, + StepsmmEaxisEnterKey = 43, + NozzlePTempEnterKey = 44, + NozzleITempEnterKey = 45, + NozzleDTempEnterKey = 46, + HotbedPTempEnterKey = 47, + HotbedITempEnterKey = 48, + HotbedDTempEnterKey = 49, + ChangePageKey = 50, + ErrorKey = 51, + StartFileKey = 52, + SelectFileKey = 53 +} proc_command_t; + +const unsigned long Addrbuf[] = { + 0x1002, + 0x1004, + 0x1006, + 0x1008, + 0x100A, // 4 + 0x100C, + 0x1026, + 0x1030, + 0x1032, + 0x1034, // 9 + 0x103A, + 0x103E, + 0x1044, + 0x1046, + 0x1048, // 14 + 0x104A, + 0x104C, + 0x1052, + 0x1054, + 0x1056, // 19 + 0x105C, + 0x105F, + 0x1090, + 0x1092, + 0x1094, // 24 + 0x1096, + 0x1098, + 0x109A, + 0x109E, + 0x10A0, // 29 + 0x10A2, + 0x10A4, + 0x10A6, + 0x10A8, + 0x10AA, // 34 + 0x10AC, + 0x10AE, + 0x10B0, + 0x10B2, + 0x10B4, // 39 + 0x10B6, + 0x10B8, + 0x10BA, + 0x10BC, + 0x10BE, // 44 + 0x10C0, + 0x10C2, + 0x10C4, + 0x10C6, + 0x10C8, // 49 + 0x110E, + 0x111A, + 0x2198, + 0x2199, + 0 +}; + +void ErrorHanding(); +void RTS_Update(); + +extern int16_t temphot; +extern int change_page_font; +extern bool wifi_enable_flag; +extern int update_time_value; +extern bool PoweroffContinue; + +extern bool G29_flag; + +extern bool flag_counter_wifi_reset; +extern bool leveling_flag; + +void RTS_PauseMoveAxisPage(); +void RTS_AutoBedLevelPage(); +void RTS_MoveAxisHoming(); +void RTS_MoveParkNozzle(); +void RTS_CommandPause(); + +typedef enum { + GO_HOME_IDLE, // idle status + GO_HOME_DOING, // now homing + GO_HOME_DONE, // at home +} AutoGoHomeSta_t; + +// Cloud printing flag +enum CloudPowerContinuePrintState { + CLOUD_PLR_NULL_STATE, + CLOUD_PLR_CHOOSE_STATE, + CLOUD_PLR_YES_STATE, + CLOUD_PLR_NO_STATE +}; + +// Cloud Print Status Flag Status +typedef enum { + COULD_PRINT_STATE_OFF, + COULD_PRINT_STATE_RUNNING, + COULD_PRINT_STATE_PAUSE, + COULD_PRINT_STATE_STOP, + COULD_PRINT_STATE_MAX +} CLOUD_PRINT_STATE_ENUM; + +extern int32_t g_couldPrintState; + +typedef struct { + // data + bool isBedLeveling; + unsigned char bedNozzleHeightState; + bool bedNozzleHeightCalFinishFlag; + unsigned char goHomeSta; + /** + * Z-axis coordinate offset: use bltouch to detect the origin and use the + * limit switch to detect the coordinates of the origin offset, this value + * is used to compensate for this offset. + */ + float zCoordinateOffset; +} BedNozzleHeightCalSt; + +extern BedNozzleHeightCalSt st_bedNozzleHeightCal; // Platform and Nozzle Height Measuring Structure +extern float bedNozzleHeightCalZ; // Platform nozzle Z-axis measurement variable +extern int8_t g_cloudPLRStatusValue; + +void AutoUIBedNozzleHeightCali(); +void LcdAutoUIMoveXYBlock(float _posX, float _posY); +void LcdAutoUIMoveZBlock(float _posZ); + +///////////////////////////////////////////////////////////////// + +void RTS_Error(const char * const err); + +void RTS_UpdateWifi(); + +void RTS_OpenFileCloud(); +void RTS_OpenedFileSD(); +void RTS_PrintStartedSD(); +void RTS_FileHasFinished(); +void RTS_SDFileCompleted(); // Called from CardReader::fileHasFinished + +void RTS_UpdatePosition(); +void RTS_UpdateFeedrate(const int16_t frp); + +void RTS_PausedPrint(); +void RTS_StepperTimeout(); +void RTS_ReheatHotend(const celsius_t c=170); +void RTS_FilamentRanOut(); +void RTS_ProbingPauseHotend(); +void RTS_ProbingResumeHotend(); +void RTS_ProbingPauseFans(); +void RTS_ProbingResumeFans(); +void RTS_LevelingUpdate(uint8_t &count, const uint8_t total); +void RTS_LevelingDone(); +void RTS_ProbingFailed(); + +// Cloud Commands +typedef enum CloudCommand : uint8_t { + CC_Connect = 0, + CC_Start, + CC_Pause, + CC_Resume, + CC_Stop, + CC_Complete, + CC_Continue +} cloudCommand_t; + +void RTS_CloudCommand(const cloudCommand_t cloud_cmd); + +void RTS_SetStatsFR(const feedRate_t fr_mm_s); +void RTS_SetStatsTime(const millis_t time); +void RTS_SetStatsRemain(const millis_t remain); + +void RTS_SetLED(const bool on); diff --git a/ini/features.ini b/ini/features.ini index 03a9bdbba8..06573bb5da 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -47,6 +47,7 @@ HAS_(FSMC|SPI|LTDC)_TFT = build_src_filter=+ I2C_EEPROM = build_src_filter=+ SOFT_I2C_EEPROM|U8G_USES_SW_I2C = SlowSoftI2CMaster, SlowSoftWire=https://github.com/felias-fogg/SlowSoftWire/archive/f34d777f39.zip SPI_EEPROM = build_src_filter=+ +CREALITY_RTS = build_src_filter=+ + + + + HAS_DWIN_E3V2|IS_DWIN_MARLINUI = build_src_filter=+ DWIN_CREALITY_LCD = build_src_filter=+ DWIN_LCD_PROUI = build_src_filter=+ @@ -333,6 +334,7 @@ EXPECTED_PRINTER_CHECK = build_src_filter=+ CAPABILITIES_REPORT = build_src_filter=+ AUTO_REPORT_POSITION = build_src_filter=+ +MENU_RESET_WIFI = build_src_filter=+ REPETIER_GCODE_M360 = build_src_filter=+ HAS_GCODE_M876 = build_src_filter=+ HAS_RESUME_CONTINUE = build_src_filter=+ @@ -369,6 +371,7 @@ HAS_PID_HEATING = build_src_filter=+ INCH_MODE_SUPPORT = build_src_filter=+ TEMPERATURE_UNITS_SUPPORT = build_src_filter=+ +CREALITY_WIFI = build_src_filter=+ NEED_HEX_PRINT = build_src_filter=+ NEED_LSF = build_src_filter=+ NOZZLE_PARK_FEATURE = build_src_filter=+ + diff --git a/platformio.ini b/platformio.ini index 9f562c0be9..8799f00e09 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,7 +58,8 @@ lib_deps = default_src_filter = + - - ; LCDs and Controllers - - - - - - - - - - - + - - - - + - - - ; Marlin HAL - @@ -82,8 +83,10 @@ default_src_filter = + - - - - - + - - - + - ; Library Code - - - @@ -118,6 +121,8 @@ default_src_filter = + - - + + + + + + + + + + From 5abc421e40db0ec363d41b98cd23950d2b3a4b97 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 6 May 2025 22:25:36 -0500 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=9A=B8=20Ender-5=20S1=20modified=20co?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/MarlinCore.cpp | 62 +- Marlin/src/feature/pause.cpp | 70 +- Marlin/src/feature/powerloss.cpp | 85 ++- Marlin/src/feature/powerloss.h | 4 + Marlin/src/feature/runout.cpp | 7 + Marlin/src/gcode/bedlevel/abl/G29.cpp | 179 ++++++ Marlin/src/gcode/calibrate/G28.cpp | 14 + Marlin/src/gcode/config/M220.cpp | 4 + Marlin/src/gcode/control/M80_M81.cpp | 6 + Marlin/src/gcode/gcode.cpp | 2 +- Marlin/src/gcode/host/M115.cpp | 21 +- Marlin/src/gcode/lcd/M0_M1.cpp | 6 + Marlin/src/gcode/motion/G0_G1.cpp | 7 +- Marlin/src/gcode/ota/M936.cpp | 16 +- Marlin/src/gcode/queue.cpp | 64 +- Marlin/src/gcode/sd/M23.cpp | 4 + Marlin/src/gcode/sd/M24_M25.cpp | 5 + Marlin/src/gcode/temp/M104_M109.cpp | 6 + Marlin/src/lcd/marlinui.cpp | 6 + Marlin/src/lcd/marlinui.h | 2 + Marlin/src/lcd/sovol_rts/sovol_rts.cpp | 1 - Marlin/src/lcd/sovol_rts/sovol_rts.h | 2 - Marlin/src/module/endstops.cpp | 3 + Marlin/src/module/motion.cpp | 607 +++++++++++++++++- Marlin/src/module/motion.h | 11 + Marlin/src/module/probe.cpp | 4 + Marlin/src/module/settings.cpp | 42 ++ Marlin/src/module/temperature.cpp | 47 +- Marlin/src/sd/cardreader.cpp | 7 + .../sd/usb_flashdrive/Sd2Card_FlashDrive.cpp | 15 +- 30 files changed, 1249 insertions(+), 60 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 6d672e3b8c..54fb48ee57 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -30,6 +30,9 @@ #include "MarlinCore.h" +#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE) +#include "core/debug_out.h" + #include "HAL/shared/Delay.h" #include "HAL/shared/esp_wifi.h" #include "HAL/shared/cpu_exception/exception_hook.h" @@ -84,6 +87,10 @@ #endif #endif +#if ENABLED(CREALITY_RTS) + #include "lcd/rts/lcd_rts.h" +#endif + #if HAS_ETHERNET #include "feature/ethernet.h" #endif @@ -397,7 +404,11 @@ void Marlin::startOrResumeJob() { TERN_(POWER_LOSS_RECOVERY, recovery.purge()); #ifdef EVENT_GCODE_SD_ABORT - queue.inject(F(EVENT_GCODE_SD_ABORT)); + DEBUG_ECHOLNPGM("abortSDPrinting"); + //queue.inject(F(EVENT_GCODE_SD_ABORT)); + queue.enqueue_now(F(EVENT_GCODE_SD_ABORT)); + report_current_position(); + TERN_(CREALITY_RTS, RTS_UpdatePosition()); #endif TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine()); @@ -442,7 +453,7 @@ void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) { if (gcode.stepper_max_timed_out(ms)) { SERIAL_ERROR_START(); SERIAL_ECHOLN(F(STR_KILL_PRE), F(STR_KILL_INACTIVE_TIME), parser.command_ptr); - kill(); + TERN(CREALITY_RTS, RTS_StepperTimeout(), kill()); } const bool has_blocks = planner.has_blocks_queued(); // Any moves in the planner? @@ -473,8 +484,10 @@ void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) { TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled()); } } - else + else { + // if (!parked_or_ignoring && gcode.stepper_inactive_timeout() && !card.isPrinting() && !card.isPaused()) // rock_20220815 already_shutdown_steppers = false; + } } #endif @@ -832,7 +845,10 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { #endif // Handle SD Card insert / remove - TERN_(HAS_MEDIA, card.manage_media()); + #if HAS_MEDIA + if (TERN1(CREALITY_RTS, !HMI_lcd_flag.home_flag && !G29_flag)) // Avoid the problem of leveling and returning to zero, plugging and unplugging the card will affect the probe and report error 203 + card.manage_media(); + #endif // Announce Host Keepalive state (if any) TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive()); @@ -844,12 +860,16 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { TERN_(HAS_BEEPER, buzzer.tick()); // Handle UI input / draw events - #if ENABLED(SOVOL_SV06_RTS) + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) RTS_Update(); #else ui.update(); #endif + #if ENABLED(PROBE_ACTIVATION_SWITCH) + endstops.enable_z_probe(TERN1(CREALITY_RTS, (HMI_lcd_flag.home_flag || G29_flag)) && (LOW == READ(PROBE_ACTIVATION_SWITCH_PIN))); + #endif + // Run i2c Position Encoders #if ENABLED(I2C_POSITION_ENCODERS) { @@ -893,6 +913,22 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { // Direct Stepping TERN_(DIRECT_STEPPING, page_manager.write_responses()); + #if ENABLED(MENU_RESET_WIFI) + static millis_t wifi_record_ms = 0; + if (rts_wifi_state == PRESSED) { + rts_wifi_state = RECORDTIME; + wifi_record_ms = millis() + 7000UL; + } + else if (rts_wifi_state == RECORDTIME) { + if (wifi_record_ms && ELAPSED(millis(), wifi_record_ms)) { + OUT_WRITE(RESET_WIFI_PIN, HIGH); + rts_wifi_state = INITIAL; + SERIAL_ECHOPGM("wifi is reset"); + wifi_record_ms = 0; + } + } + #endif + // Update the LVGL interface TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER()); @@ -1316,13 +1352,13 @@ void setup() { // Identify myself as Marlin x.x.x SERIAL_ECHOLNPGM("Marlin " SHORT_BUILD_VERSION); - #ifdef STRING_DISTRIBUTION_DATE + #if defined(STRING_DISTRIBUTION_DATE) && (DISABLED(CREALITY_RTS) || defined(STRING_CONFIG_H_AUTHOR)) SERIAL_ECHO_MSG( " Last Updated: " STRING_DISTRIBUTION_DATE " | Author: " STRING_CONFIG_H_AUTHOR ); #endif - SERIAL_ECHO_MSG(" Compiled: " __DATE__); + SERIAL_ECHO_MSG(" Compiled: " __DATE__ " " __TIME__); SERIAL_ECHO_MSG(STR_FREE_MEMORY, hal.freeMemory(), STR_PLANNER_BUFFER_BYTES, sizeof(block_t) * (BLOCK_BUFFER_SIZE)); // Some HAL need precise delay adjustment @@ -1650,7 +1686,7 @@ void setup() { #if ENABLED(DWIN_CREALITY_LCD) SETUP_RUN(dwinInitScreen()); - #elif ENABLED(SOVOL_SV06_RTS) + #elif ANY(SOVOL_SV06_RTS, CREALITY_RTS) SETUP_RUN(rts.init()); #endif @@ -1758,3 +1794,13 @@ void loop() { } while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards } + +//void HardFault_Handler(void) { +// SERIAL_ECHO_MSG("HardFault_Handler"); +// OUT_WRITE(E0_AUTO_FAN_PIN, LOW); +// OUT_WRITE(FAN_PIN, LOW); +// for (int i = 0; i < 0xFFFF; i++) OUT_WRITE(FAN_PIN, HIGH); +// OUT_WRITE(E0_AUTO_FAN_PIN, HIGH); +// OUT_WRITE(FAN_PIN, HIGH); +// while(1); +//} diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 025bcb8383..96ed7b0f72 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -68,6 +68,10 @@ #include "../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #if HAS_SOUND #include "../libs/buzzer.h" #endif @@ -159,11 +163,13 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P if (wait) return thermalManager.wait_for_hotend(active_extruder); - // Allow interruption by Emergency Parser M108 - marlin.wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); - while (marlin.is_heating() && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) - marlin.idle(); - marlin.heatup_done(); + #if DISABLED(CREALITY_RTS) + // Allow interruption by Emergency Parser M108 + marlin.wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); + while (marlin.is_heating() && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) + marlin.idle(); + marlin.wait_for_heatup = false; + #endif #if ENABLED(PREVENT_COLD_EXTRUSION) // A user can cancel wait-for-heating with M108 @@ -431,6 +437,7 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh #endif TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR))); + TERN_(CREALITY_RTS, RTS_PausedPrint()); // Indicate that the printer is paused ++did_pause_print; @@ -479,9 +486,29 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh TERN_(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(leveling_was_enabled)); // restore leveling } - // If axes don't need to home then the nozzle can park - if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move - if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED); + #if ENABLED(CREALITY_RTS) + + while (planner.movesplanned() < 2 && destination != current_position) + marlin.idle(); + + queue.clear(); + delay(20); + if (!planner.has_blocks_queued()) { + if (axis_is_trusted(X_AXIS) && axis_is_trusted(Y_AXIS)) { + //if (!axes_need_homing()) + nozzle.park(0, park_point); + } + } + + #else + + // If axes don't need to home then the nozzle can park + if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move + if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED); + + #endif + + TERN_(DWIN_LCD_PROUI, if (!do_park) ui.set_status(GET_TEXT_F(MSG_PARK_FAILED))); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -489,15 +516,19 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh set_duplication_enabled(false, DXC_ext); #endif - // Unload the filament, if specified - if (unload_length) - unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); + #if DISABLED(CREALITY_RTS) + // Unload the filament, if specified + if (unload_length) + unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); + #endif TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); // Disable the Extruder for manual change disable_active_extruder(); + TERN_(CREALITY_RTS, RTS_ReheatHotend(170)); + return true; } @@ -611,6 +642,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep nozzle_timed_out = false; first_impatient_beep(max_beep_count); } + TERN_(CREALITY_RTS, marlin.wait_for_user = false); marlin.idle_no_sleep(); } TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); @@ -696,13 +728,17 @@ void resume_print( unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); if (!axes_should_home()) { - // Move XY back to saved position - destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e); - prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); + #if ENABLED(CREALITY_RTS) + destination.set(resume_position.x, resume_position.y, resume_position.z, current_position.e); + #else + // Move XY back to saved position + destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e); + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); - // Move Z back to saved position - destination.z = resume_position.z; - prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + // Move Z back to saved position + destination.z = resume_position.z; + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + #endif } #if ENABLED(AUTO_BED_LEVELING_UBL) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 0dd19808bc..f0ad4425ac 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -53,6 +53,11 @@ uint32_t PrintJobRecovery::cmd_sdpos, // = 0 bool PrintJobRecovery::ui_flag_resume; // = false #endif +#if ENABLED(CREALITY_RTS) + bool PrintJobRecovery::recovery_flag; // = false + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../sd/cardreader.h" #include "../lcd/marlinui.h" #include "../gcode/queue.h" @@ -96,6 +101,20 @@ PrintJobRecovery recovery; gcode.process_subcommands_now(cmd); \ }while(0) +#if ENABLED(CREALITY_RTS) + // Feed action before pausing and resuming。rock_20220914 + #define FEEDING_DEF_DISTANCE 5 // in material: default distance of feeding material + #define FEEDING_DEF_SPEED 5 // in material: default feedrate + static void pause_resume_feedstock(uint16_t _distance, uint16_t _feedRate) { + current_position.e += _distance; + line_to_current_position(feedRate_t(_feedRate)); + current_position.e -= _distance; + gcode.process_subcommands_now(TS(F("G92.9 E"), p_float_t(current_position.e, 3))); + // Resume the feedrate + gcode.process_subcommands_now(TS(F("G1 F%s"), p_float_t(MMS_TO_MMM(feedrate_mm_s), 3))); + } +#endif + /** * Clear the recovery info */ @@ -216,6 +235,11 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW // Machine state // info.sdpos and info.current_position are pre-filled from the Stepper ISR + #if ENABLED(CREALITY_RTS) + //report_current_position(); //rock_0328 + //info.current_position = current_position; + #endif + info.feedrate = uint16_t(MMS_TO_MMM(feedrate_mm_s)); info.feedrate_percentage = feedrate_percentage; COPY(info.flow_percentage, planner.flow_percentage); @@ -270,7 +294,11 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW info.flag.dryrun = !!(marlin_debug_flags & MARLIN_DEBUG_DRYRUN); info.flag.allow_cold_extrusion = TERN0(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude); + TERN_(CREALITY_RTS, recovery_flag = PoweroffContinue); + write(); + + DEBUG_ECHO_MSG("current_position.z:", current_position.z); } } @@ -441,6 +469,8 @@ void PrintJobRecovery::resume() { const float z_raised = z_print + info.zraise; #endif + DEBUG_ECHO_MSG(">>> z_print:", z_print, ", z_raised:", z_raised, ", info.flag.raised:", info.flag.raised); + // // Home the axes that can safely be homed, and // establish the current position as best we can. @@ -486,21 +516,27 @@ void PrintJobRecovery::resume() { #if HOMING_Z_DOWN // Move to a safe XY position and home Z while avoiding the print. const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy); - PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28HZ"))); + PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28ZH" TERN_(CREALITY_RTS, "R0")))); #endif // Mark all axes as having been homed (no effect on current_position) set_all_homed(); + DEBUG_ECHO_MSG(">>> homed current_position.z:", current_position.z); + #if HAS_LEVELING // Restore Z fade and possibly re-enable bed leveling compensation. // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. // TODO: Add a G28 parameter to leave leveling disabled. - PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + (char)info.flag.leveling, 'Z', p_float_t(info.fade, 1))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + (char)info.flag.leveling, 'Z', p_float_t(info.fade, 1))); + #endif #if !HOMING_Z_DOWN // The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9. - PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3))); + #endif #endif #endif @@ -576,13 +612,37 @@ void PrintJobRecovery::resume() { PROCESS_SUBCOMMANDS_NOW(F("G12")); #endif + #if ENABLED(CREALITY_RTS) + + PROCESS_SUBCOMMANDS_NOW(F("M420 S0 Z0")); // rock_20220326 + + // Restore E position with G92.9 Rock_20220913 + // If there is a layer-changing and retracting action in GCODE, + // first extrude the material and then return to the origin + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(info.current_position.e, 3))); + + // rock_20220914 - To solve the problem of faults in the printed small model, + // the purpose is to fill the hollow section of the throat. + pause_resume_feedstock(FEEDING_DEF_DISTANCE, FEEDING_DEF_SPEED); + + #endif + // Move back over to the saved XY PROCESS_SUBCOMMANDS_NOW(TS( F("G1F3000X"), p_float_t(resume_pos.x, 3), 'Y', p_float_t(resume_pos.y, 3) )); // Move back down to the saved Z for printing - PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3))); + #if ENABLED(CREALITY_RTS) + MString<20> cmd(F("G1F600Z"), p_float_t(z_print, 3)); + PROCESS_SUBCOMMANDS_NOW(cmd); + DEBUG_ECHOLN(&cmd); + DEBUG_ECHO_MSG(">>> z_print:", z_print, "current_position.z:", current_position.z); + PROCESS_SUBCOMMANDS_NOW(F("M114")); + //safe_delay(10000); + #else + PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3))); + #endif // Restore the feedrate and percentage PROCESS_SUBCOMMANDS_NOW(TS(F("G1F"), info.feedrate)); @@ -591,8 +651,20 @@ void PrintJobRecovery::resume() { // Flowrate percentage EXTRUDER_LOOP() planner.set_flow(e, info.flow_percentage[e]); + #if ALL(CREALITY_RTS, HAS_LEVELING) + // Restore Z fade and possibly re-enable bed leveling compensation. + // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. + // TODO: Add a G28 parameter to leave leveling disabled. + PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + char(info.flag.leveling), 'Z', p_float_t(info.fade, 1))); + + // Restore Z position with G92.9 + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_print, 3))); + #endif + // Restore E position with G92.9 - PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); + #endif #if ENABLED(CANCEL_OBJECTS) cancelable.state = info.cancel_state; @@ -743,6 +815,9 @@ void PrintJobRecovery::resume() { #if HAS_VOLUMETRIC_EXTRUSION DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); #endif + #if ENABLED(CREALITY_RTS) + DEBUG_ECHOLNPGM("recovery_flag: ", AS_DIGIT(recovery_flag)); + #endif } else DEBUG_ECHOLNPGM("INVALID DATA"); diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index bfa5b4717f..ae0671158c 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -166,6 +166,10 @@ class PrintJobRecovery { static bool ui_flag_resume; //!< Flag the UI to show a dialog to Resume (M1000) or Cancel (M1000C) #endif + #if ENABLED(CREALITY_RTS) + static bool recovery_flag; + #endif + static void init(); static void prepare(); diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index f0b94d0de8..16bfc1bf46 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -30,6 +30,10 @@ #include "runout.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + FilamentMonitor runout; bool FilamentMonitorBase::enabled = true, @@ -75,6 +79,7 @@ bool FilamentMonitorBase::enabled = true, #endif void event_filament_runout(const uint8_t extruder) { + if (TERN0(CREALITY_RTS, G29_flag || home_flag)) return; runout.init_for_restart(false); // Reset and disable @@ -104,6 +109,8 @@ void event_filament_runout(const uint8_t extruder) { const bool run_runout_script = !runout.host_handling; + TERN_(CREALITY_RTS, RTS_FilamentRanOut()); + #if ENABLED(HOST_ACTION_COMMANDS) const bool park_or_pause = (false diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 800d51dac6..3ba298544b 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -35,6 +35,12 @@ #include "../../../module/probe.h" #include "../../../module/temperature.h" #include "../../queue.h" +#include "../../../module/settings.h" +#include "../../../sd/cardreader.h" + +#if ENABLED(CREALITY_RTS) + #include "../../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) #include "../../../libs/least_squares_fit.h" @@ -108,6 +114,10 @@ public: bool dryrun, reenable; + #if ENABLED(CREALITY_RTS) + uint8_t showcount; + #endif + #if ANY(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR) int abl_probe_index; #endif @@ -155,6 +165,124 @@ public: constexpr grid_count_t G29_State::abl_points; #endif +#if ALL(HAS_MESH, CREALITY_RTS) + + void apply_mesh_correction(bed_mesh_t &z_values) { + float grok[3][5][5] = { 0 }; + + // lower left corner + grok[0][0][0] = -((z_values[0][4] - z_values[0][3]) + (z_values[0][3] - z_values[0][2]) + (z_values[0][2] - z_values[0][1])) / 3.0f + z_values[0][1]; + grok[1][0][0] = -((z_values[4][0] - z_values[3][0]) + (z_values[3][0] - z_values[2][0]) + (z_values[2][0] - z_values[1][0])) / 3.0f + z_values[1][0]; + grok[2][0][0] = -((z_values[4][4] - z_values[3][3]) + (z_values[3][3] - z_values[2][2]) + (z_values[2][2] - z_values[1][1])) / 3.0f + z_values[1][1]; + + grok[0][0][1] = -((z_values[0][4] - z_values[0][3]) + (z_values[0][3] - z_values[0][2])) / 2.0f + z_values[0][2]; + grok[1][0][1] = -((z_values[4][1] - z_values[3][1]) + (z_values[3][1] - z_values[2][1]) + (z_values[2][1] - z_values[1][1])) / 3.0f + z_values[1][1]; + grok[2][0][1] = -((z_values[3][4] - z_values[2][3]) + (z_values[2][3] - z_values[1][2])) / 2.0f + z_values[1][2]; + + grok[0][1][0] = -((z_values[1][4] - z_values[1][3]) + (z_values[1][3] - z_values[1][2]) + (z_values[1][2] - z_values[1][1])) / 3.0f + z_values[1][1]; + grok[1][1][0] = -((z_values[4][0] - z_values[3][0]) + (z_values[3][0] - z_values[2][0])) / 2.0f + z_values[2][0]; + grok[2][1][0] = -((z_values[4][3] - z_values[3][2]) + (z_values[3][2] - z_values[2][1])) / 2.0f + z_values[2][1]; + + grok[0][1][1] = -((z_values[1][4] - z_values[1][3]) + (z_values[1][3] - z_values[1][2])) / 2.0f + z_values[1][2]; + grok[1][1][1] = -((z_values[4][1] - z_values[3][1]) + (z_values[3][1] - z_values[2][1])) / 2.0f + z_values[2][1]; + grok[2][1][1] = -((z_values[4][4] - z_values[3][3]) + (z_values[3][3] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // upper left corner + grok[0][0][4] = -((z_values[4][4] - z_values[3][4]) + (z_values[3][4] - z_values[2][4]) + (z_values[2][4] - z_values[1][4])) / 3.0f + z_values[1][4]; + grok[1][0][4] = -((z_values[0][0] - z_values[0][1]) + (z_values[0][1] - z_values[0][2]) + (z_values[0][2] - z_values[0][3])) / 3.0f + z_values[0][3]; + grok[2][0][4] = -((z_values[4][0] - z_values[3][1]) + (z_values[3][1] - z_values[2][2]) + (z_values[2][2] - z_values[1][3])) / 3.0f + z_values[1][3]; + + grok[0][0][3] = -((z_values[4][3] - z_values[3][3]) + (z_values[3][3] - z_values[2][3]) + (z_values[2][3] - z_values[1][3])) / 3.0f + z_values[1][3]; + grok[1][0][3] = -((z_values[0][0] - z_values[0][1]) + (z_values[0][1] - z_values[0][2])) / 2.0f + z_values[0][2]; + grok[2][0][3] = -((z_values[3][0] - z_values[2][1]) + (z_values[2][1] - z_values[1][2])) / 2.0f + z_values[1][2]; + + grok[0][1][4] = -((z_values[1][0] - z_values[1][1]) + (z_values[1][1] - z_values[1][2]) + (z_values[1][2] - z_values[1][3])) / 3.0f + z_values[1][3]; + grok[1][1][4] = -((z_values[4][4] - z_values[3][4]) + (z_values[3][4] - z_values[2][4])) / 2.0f + z_values[2][4]; + grok[2][1][4] = -((z_values[4][1] - z_values[3][2]) + (z_values[3][2] - z_values[2][3])) / 2.0f + z_values[2][3]; + + grok[0][1][3] = -((z_values[4][3] - z_values[3][3]) + (z_values[3][3] - z_values[2][3])) / 2.0f + z_values[2][3]; + grok[1][1][3] = -((z_values[1][0] - z_values[1][1]) + (z_values[1][1] - z_values[1][2])) / 2.0f + z_values[1][2]; + grok[2][1][3] = -((z_values[4][0] - z_values[3][1]) + (z_values[3][1] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // upper right corner + grok[0][4][4] = -((z_values[0][4] - z_values[1][4]) + (z_values[1][4] - z_values[2][4]) + (z_values[2][4] - z_values[3][4])) / 3.0f + z_values[3][4]; + grok[1][4][4] = -((z_values[4][0] - z_values[4][1]) + (z_values[4][1] - z_values[4][2]) + (z_values[4][2] - z_values[4][3])) / 3.0f + z_values[4][3]; + grok[2][4][4] = -((z_values[0][0] - z_values[1][1]) + (z_values[1][1] - z_values[2][2]) + (z_values[2][2] - z_values[3][3])) / 3.0f + z_values[3][3]; + + grok[0][3][4] = -((z_values[3][0] - z_values[3][1]) + (z_values[3][1] - z_values[3][2]) + (z_values[3][2] - z_values[3][3])) / 3.0f + z_values[3][3]; + grok[1][3][4] = -((z_values[0][4] - z_values[1][4]) + (z_values[1][4] - z_values[2][4])) / 2.0f + z_values[2][4]; + grok[2][3][4] = -((z_values[0][1] - z_values[1][2]) + (z_values[1][2] - z_values[2][3])) / 2.0f + z_values[2][3]; + + grok[0][4][3] = -((z_values[0][3] - z_values[1][3]) + (z_values[1][3] - z_values[2][3]) + (z_values[2][3] - z_values[3][3])) / 3.0f + z_values[3][3]; + grok[1][4][3] = -((z_values[4][0] - z_values[4][1]) + (z_values[4][1] - z_values[4][2])) / 2.0f + z_values[4][2]; + grok[2][4][3] = -((z_values[1][0] - z_values[2][1]) + (z_values[2][1] - z_values[3][2])) / 2.0f + z_values[3][2]; + + grok[0][3][3] = -((z_values[0][3] - z_values[1][3]) + (z_values[1][3] - z_values[2][3])) / 2.0f + z_values[2][3]; + grok[1][3][3] = -((z_values[3][0] - z_values[3][1]) + (z_values[3][1] - z_values[3][2])) / 2.0f + z_values[3][2]; + grok[2][3][3] = -((z_values[0][0] - z_values[1][1]) + (z_values[1][1] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // lower right corner + grok[0][4][0] = -((z_values[4][4] - z_values[4][3]) + (z_values[4][3] - z_values[4][2]) + (z_values[4][2] - z_values[4][1])) / 3.0f + z_values[4][1]; + grok[1][4][0] = -((z_values[0][0] - z_values[1][0]) + (z_values[1][0] - z_values[2][0]) + (z_values[2][0] - z_values[3][0])) / 3.0f + z_values[3][0]; + grok[2][4][0] = -((z_values[0][4] - z_values[1][3]) + (z_values[1][3] - z_values[2][2]) + (z_values[2][2] - z_values[3][1])) / 3.0f + z_values[3][1]; + + grok[0][3][0] = -((z_values[3][4] - z_values[3][3]) + (z_values[3][3] - z_values[3][2]) + (z_values[3][2] - z_values[3][1])) / 3.0f + z_values[3][1]; + grok[1][3][0] = -((z_values[0][0] - z_values[1][0]) + (z_values[1][0] - z_values[2][0])) / 2.0f + z_values[2][0]; + grok[2][3][0] = -((z_values[0][3] - z_values[1][2]) + (z_values[1][2] - z_values[2][1])) / 2.0f + z_values[2][1]; + + grok[0][4][1] = -((z_values[0][1] - z_values[1][1]) + (z_values[1][1] - z_values[2][1]) + (z_values[2][1] - z_values[3][1])) / 3.0f + z_values[3][1]; + grok[1][4][1] = -((z_values[4][4] - z_values[4][3]) + (z_values[4][3] - z_values[4][2])) / 2.0f + z_values[4][2]; + grok[2][4][1] = -((z_values[1][4] - z_values[2][3]) + (z_values[2][3] - z_values[3][2])) / 2.0f + z_values[3][2]; + + grok[0][3][1] = -((z_values[3][4] - z_values[3][3]) + (z_values[3][3] - z_values[3][2])) / 2.0f + z_values[3][2]; + grok[1][3][1] = -((z_values[0][1] - z_values[1][1]) + (z_values[1][1] - z_values[2][1])) / 2.0f + z_values[2][1]; + grok[2][3][1] = -((z_values[0][4] - z_values[1][3]) + (z_values[1][3] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // Calculate mean + z_values[0][0] = (grok[0][0][0] + grok[1][0][0] + grok[2][0][0]) / 3.0f; + z_values[0][1] = (grok[0][0][1] + grok[1][0][1] + grok[2][0][1] + z_values[0][1]) / 4.0f; + z_values[1][0] = (grok[0][1][0] + grok[1][1][0] + grok[2][1][0] + z_values[1][0]) / 4.0f; + z_values[1][1] = (grok[0][1][1] + grok[1][1][1] + grok[2][1][1] + z_values[1][1]) / 4.0f; + + z_values[0][4] = (grok[0][0][4] + grok[1][0][4] + grok[2][0][4] + z_values[0][4]) / 4.0f; + z_values[0][3] = (grok[0][0][3] + grok[1][0][3] + grok[2][0][3] + z_values[0][3]) / 4.0f; + z_values[1][4] = (grok[0][1][4] + grok[1][1][4] + grok[2][1][4] + z_values[1][4]) / 4.0f; + z_values[1][3] = (grok[0][1][3] + grok[1][1][3] + grok[2][1][3] + z_values[1][3]) / 4.0f; + + z_values[4][4] = (grok[0][4][4] + grok[1][4][4] + grok[2][4][4] + z_values[4][4]) / 4.0f; + z_values[3][4] = (grok[0][3][4] + grok[1][3][4] + grok[2][3][4] + z_values[3][4]) / 4.0f; + z_values[4][3] = (grok[0][4][3] + grok[1][4][3] + grok[2][4][3] + z_values[4][3]) / 4.0f; + z_values[3][3] = (grok[0][3][3] + grok[1][3][3] + grok[2][3][3] + z_values[3][3]) / 4.0f; + + z_values[4][0] = (grok[0][4][0] + grok[1][4][0] + grok[2][4][0] + z_values[4][0]) / 4.0f; + z_values[3][0] = (grok[0][3][0] + grok[1][3][0] + grok[2][3][0] + z_values[3][0]) / 4.0f; + z_values[4][1] = (grok[0][4][1] + grok[1][4][1] + grok[2][4][1] + z_values[4][1]) / 4.0f; + z_values[3][1] = (grok[0][3][1] + grok[1][3][1] + grok[2][3][1] + z_values[3][1]) / 4.0f; + + // weighted calculation method + //z_values[0][0] = (grok[0][0][0] + grok[1][0][0] + grok[2][0][0]) / 3.0f * 0.4f + z_values[0][0] * 0.6; + //z_values[0][1] = (grok[0][0][1] + grok[1][0][1] + grok[2][0][1]) / 3.0f * 0.4f + z_values[0][1] * 0.6; + //z_values[1][0] = (grok[0][1][0] + grok[1][1][0] + grok[2][1][0]) / 3.0f * 0.4f + z_values[1][0] * 0.6; + //z_values[1][1] = (grok[0][1][1] + grok[1][1][1] + grok[2][1][1]) / 3.0f * 0.4f + z_values[1][1] * 0.6; + + //z_values[0][4] = (grok[0][0][4] + grok[1][0][4] + grok[2][0][4]) / 3.0f * 0.4f + z_values[0][4] * 0.6; + //z_values[0][3] = (grok[0][0][3] + grok[1][0][3] + grok[2][0][3]) / 3.0f * 0.4f + z_values[0][3] * 0.6; + //z_values[1][4] = (grok[0][1][4] + grok[1][1][4] + grok[2][1][4]) / 3.0f * 0.4f + z_values[1][4] * 0.6; + //z_values[1][3] = (grok[0][1][3] + grok[1][1][3] + grok[2][1][3]) / 3.0f * 0.4f + z_values[1][3] * 0.6; + + //z_values[4][4] = (grok[0][4][4] + grok[1][4][4] + grok[2][4][4]) / 3.0f * 0.4f + z_values[4][4] * 0.6; + //z_values[3][4] = (grok[0][3][4] + grok[1][3][4] + grok[2][3][4]) / 3.0f * 0.4f + z_values[3][4] * 0.6; + //z_values[4][3] = (grok[0][4][3] + grok[1][4][3] + grok[2][4][3]) / 3.0f * 0.4f + z_values[4][3] * 0.6; + //z_values[3][3] = (grok[0][3][3] + grok[1][3][3] + grok[2][3][3]) / 3.0f * 0.4f + z_values[3][3] * 0.6; + + //z_values[4][0] = (grok[0][4][0] + grok[1][4][0] + grok[2][4][0]) / 3.0f * 0.4f + z_values[4][0] * 0.6; + //z_values[3][0] = (grok[0][3][0] + grok[1][3][0] + grok[2][3][0]) / 3.0f * 0.4f + z_values[3][0] * 0.6; + //z_values[4][1] = (grok[0][4][1] + grok[1][4][1] + grok[2][4][1]) / 3.0f * 0.4f + z_values[4][1] * 0.6; + //z_values[3][1] = (grok[0][3][1] + grok[1][3][1] + grok[2][3][1]) / 3.0f * 0.4f + z_values[3][1] * 0.6; + } + +#endif // HAS_MESH && CREALITY_RTS + /** * G29: Bed Leveling * @@ -233,6 +361,14 @@ G29_TYPE GcodeSuite::G29() { // Keep powered steppers from timing out reset_stepper_timeout(); + reset_bed_level(); // not 0 but NaN + + #if ENABLED(CREALITY_RTS) + G29_flag = true; + RTS_ProbingPauseHotend(); + RTS_ProbingPauseFans(); + #endif + // Q = Query leveling and G29 state const bool seenQ = ANY(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q'); @@ -621,6 +757,7 @@ G29_TYPE GcodeSuite::G29() { // Is there a next point to move to? if (abl.abl_probe_index < abl.abl_points) { + //abl.probePos.y -= probe.offset.y; _manual_goto_xy(abl.probePos); // Can be used here too! // Disable software endstops to allow manual adjustment // If G29 is not completed, they will not be re-enabled @@ -677,6 +814,7 @@ G29_TYPE GcodeSuite::G29() { // Outer loop is X with PROBE_Y_FIRST enabled // Outer loop is Y with PROBE_Y_FIRST disabled + TERN_(CREALITY_RTS, abl.showcount = 0); for (PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_SIZE && !isnan(abl.measured_z); PR_OUTER_VAR++) { int8_t inStart, inStop, inInc; @@ -793,6 +931,7 @@ G29_TYPE GcodeSuite::G29() { const float z = abl.measured_z + abl.Z_offset; abl.z_values[abl.meshCount.x][abl.meshCount.y] = z; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z)); + TERN_(CREALITY_RTS, RTS_LevelingUpdate(abl.showcount, abl.abl_points)); #if ENABLED(SOVOL_SV06_RTS) if (pt_index <= GRID_MAX_POINTS) rts.sendData(pt_index, AUTO_BED_LEVEL_ICON_VP); @@ -808,6 +947,28 @@ G29_TYPE GcodeSuite::G29() { } // inner } // outer + // Leveling data compensation interface + //for (uint8_t index = 0; index <= 3; ++index) { + // //bedlevel.z_values[3][index] *= 1.3f; + // //bedlevel.z_values[2][index] *= 1.3f; + // //bedlevel.z_values[2][index] += bedlevel.z_values[1][index] * 0.3f; + // //bedlevel.z_values[0][index] *= 1.3f; + // bedlevel.z_values[index][1] *= 0.8f; + // bedlevel.z_values[index][2] *= 0.8f; + // bedlevel.z_values[index][3] *= 0.8f; + // bedlevel.z_values[index][0] *= 0.8f; + //} + + TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.print_leveling_grid()); // print raw data + + // Force smoothing of the bottom left corner data + //float bedlevel.z_valuesTemp = 0; + //bedlevel.z_valuesTemp = (bedlevel.z_values[0][0] + bedlevel.z_values[0][1] + bedlevel.z_values[1][0]) / 3.0f; + //bedlevel.z_values[0][0] -= 0.08f; + //bedlevel.z_values[0][1] -= 0.05f; + //bedlevel.z_values[1][0] -= 0.05f; + //bedlevel.z_values[1][1] -= 0.02f; + #elif ENABLED(AUTO_BED_LEVELING_3POINT) // Probe at 3 arbitrary points @@ -837,6 +998,10 @@ G29_TYPE GcodeSuite::G29() { #endif // AUTO_BED_LEVELING_3POINT + #if ALL(HAS_MESH, CREALITY_RTS) + apply_mesh_correction(bedlevel.z_values); + #endif + ui.reset_status(); // Stow the probe. No raise for FIX_MOUNTED_PROBE. @@ -1021,9 +1186,23 @@ G29_TYPE GcodeSuite::G29() { probe.use_probing_tool(false); + #if ENABLED(Z_SAFE_HOMING) + do_blocking_move_to_xy(Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT); + //do_blocking_move_to_xy(Z_SAFE_HOMING_X_POINT-2, Z_SAFE_HOMING_Y_POINT+44.5);//rock_20220610 将Z轴复位后的终点改成平台中心 + #endif + + settings.save(); + report_current_position(); + #if ENABLED(CREALITY_RTS) + RTS_LevelingDone(); + RTS_ProbingResumeFans(); + RTS_ProbingResumeHotend(); + #endif + G29_RETURN(isnan(abl.measured_z), true); + } #endif // HAS_ABL_NOT_UBL diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 4a0ecffc4b..b8c48937fe 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -66,6 +66,10 @@ #include "../../lcd/sovol_rts/sovol_rts.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(LASER_FEATURE) #include "../../feature/spindle_laser.h" #endif @@ -254,6 +258,7 @@ void GcodeSuite::G28() { #endif TERN_(DWIN_CREALITY_LCD, dwinHomingStart()); + TERN_(CREALITY_RTS, home_flag = true); TERN_(EXTENSIBLE_UI, ExtUI::onHomingStart()); planner.synchronize(); // Wait for planner moves to finish! @@ -578,6 +583,15 @@ void GcodeSuite::G28() { TERN_(DWIN_CREALITY_LCD, dwinHomingDone()); TERN_(EXTENSIBLE_UI, ExtUI::onHomingDone()); + #if ENABLED(CREALITY_RTS) + home_flag = false; + RTS_MoveAxisHoming(); + //DEBUG_ECHOLNPGM(" leveling_flag=: ", leveling_flag); + // If it is in leveling, the automatic compensation function will not be restored + //process_subcommands_now_P(leveling_flag ? PSTR("M420 S0") : PSTR("M420 S1 Z10")); + st_bedNozzleHeightCal.goHomeSta = GO_HOME_DONE; + #endif + report_current_position(); TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(old_grblstate)); diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp index 0d1e204800..67d2a5e91d 100644 --- a/Marlin/src/gcode/config/M220.cpp +++ b/Marlin/src/gcode/config/M220.cpp @@ -22,6 +22,9 @@ #include "../gcode.h" #include "../../module/motion.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif /** * M220: Set Feedrate Percentage @@ -46,4 +49,5 @@ void GcodeSuite::M220() { if (parser.seen_test('B')) backup_feedrate_percentage = now_feedrate_perc; if (parser.seenval('S')) feedrate_percentage = parser.value_int(); + TERN_(CREALITY_RTS, RTS_UpdateFeedrate(feedrate_percentage)); } diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index a7653a4037..e8b38cf3b0 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -42,6 +42,10 @@ #include "../../MarlinCore.h" #endif +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../feature/powerloss.h" +#endif + #if ENABLED(PSU_CONTROL) /** @@ -127,4 +131,6 @@ void GcodeSuite::M81() { #elif HAS_SUICIDE marlin.suicide(); #endif + + //OUT_WRITE(SHUTDOWN_PIN, LOW); delay(2000); } diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 8b35400c52..4d620155bc 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -1301,7 +1301,7 @@ void GcodeSuite::process_subcommands_now(char * gcode) { TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_position_moving()); break; case PAUSED_FOR_USER: - SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER); + if (TERN1(CREALITY_RTS, change_page_font == 7)) SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER); TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD)); break; case PAUSED_FOR_INPUT: diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 19d0ae9b63..c5250798c4 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -39,6 +39,10 @@ #include "../../libs/hex_print.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + //#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities #if ENABLED(EXTENDED_CAPABILITIES_REPORT) @@ -46,11 +50,14 @@ #if ENABLED(MINIMAL_CAP_LINES) if (ena) SERIAL_ECHOLNPGM("Cap:", name, ":1"); #else - SERIAL_ECHOPGM("Cap:", name); - SERIAL_CHAR(':', '0' + ena); - SERIAL_EOL(); + SERIAL_ECHOLN(F("Cap:"), name, C(':'), C('0' + ena)); #endif } + #if ENABLED(CREALITY_RTS) + inline void cap_line_uchar(FSTR_P const name, const uint8_t ena) { + SERIAL_ECHOLN(F("Cap:"), name, C(':'), C('0' + ena)); + } + #endif #endif /** @@ -135,6 +142,11 @@ void GcodeSuite::M115() { // BINARY_FILE_TRANSFER (M28 B1) cap_line(F("BINARY_FILE_TRANSFER"), ENABLED(BINARY_FILE_TRANSFER)); // TODO: Use SERIAL_IMPL.has_feature(port, SerialFeature::BinaryFileTransfer) once implemented + #if ENABLED(CREALITY_RTS) + // Creality New Cloud Print Information + cap_line_uchar(F("IS_PLR"), g_cloudPLRStatusValue); // Send status to continue print after power failure + #endif + // EEPROM (M500, M501) cap_line(F("EEPROM"), ENABLED(EEPROM_SETTINGS)); @@ -247,6 +259,9 @@ void GcodeSuite::M115() { // CONFIG_EXPORT cap_line(F("CONFIG_EXPORT"), ENABLED(CONFIGURATION_EMBEDDING)); + // Creality WiFi + TERN_(CREALITY_RTS, cap_line(F("WIFI"), wifi_enable_flag)); + // Machine Geometry #if ENABLED(M115_GEOMETRY_REPORT) constexpr xyz_pos_t bmin{0}, diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp index 81c16ebdfe..63d0e345ea 100644 --- a/Marlin/src/gcode/lcd/M0_M1.cpp +++ b/Marlin/src/gcode/lcd/M0_M1.cpp @@ -36,6 +36,9 @@ #include "../../lcd/extui/ui_api.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(HOST_PROMPT_SUPPORT) #include "../../feature/host_actions.h" #endif @@ -45,6 +48,9 @@ * M1: Conditional stop - Wait for user button press on LCD */ void GcodeSuite::M0_M1() { + + TERN_(CREALITY_RTS, RTS_CommandPause()); + millis_t ms = 0; if (parser.seenval('P')) ms = parser.value_millis(); // Milliseconds to wait if (parser.seenval('S')) ms = parser.value_millis_from_seconds(); // Seconds to wait diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp index b489b659ae..36305653c8 100644 --- a/Marlin/src/gcode/motion/G0_G1.cpp +++ b/Marlin/src/gcode/motion/G0_G1.cpp @@ -22,6 +22,9 @@ #include "../gcode.h" #include "../../module/motion.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #include "../../MarlinCore.h" @@ -122,5 +125,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving()); #endif - TERN_(SOVOL_SV06_RTS, RTS_PauseMoveAxisPage()); + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) + RTS_PauseMoveAxisPage(); + #endif } diff --git a/Marlin/src/gcode/ota/M936.cpp b/Marlin/src/gcode/ota/M936.cpp index 353e423c77..0b94ceb597 100644 --- a/Marlin/src/gcode/ota/M936.cpp +++ b/Marlin/src/gcode/ota/M936.cpp @@ -26,6 +26,10 @@ #include "../gcode.h" #include "../../libs/BL24CXX.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #define OTA_FLAG_EEPROM 90 //#define DEBUG_OUT 1 @@ -43,11 +47,21 @@ void GcodeSuite::M936() { // Set the OTA board firmware upgrade flag ahead of reboot. ota_update_flag = 0x01; DEBUG_ECHOLNPGM("Motherboard upgrade flag set"); + TERN_(CREALITY_RTS, RTS_Error(Error_205)); break; + + #if ENABLED(CREALITY_RTS) + case 3: + // Set the OTA screen firmware upgrade flag ahead of reboot. + ota_update_flag = 0x02; + DEBUG_ECHOLNPGM("DWIN upgrade flag set"); + TERN_(CREALITY_RTS, RTS_Error(Error_206)); + break; + #endif } switch (ota) { - case 2: + case 2: TERN_(CREALITY_RTS, case 3:) BL24CXX::write(OTA_FLAG_EEPROM, &ota_update_flag, sizeof(ota_update_flag)); safe_delay(100); hal.reboot(); diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 0014ca44a5..34b6e2b447 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -37,6 +37,10 @@ GCodeQueue queue; #include "../MarlinCore.h" #include "../core/bug_on.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(BINARY_FILE_TRANSFER) #include "../feature/binary_stream.h" #endif @@ -112,7 +116,10 @@ void GCodeQueue::RingBuffer::commit_command(const bool skip_ok bool GCodeQueue::RingBuffer::enqueue(const char *cmd, const bool skip_ok/*=true*/ OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind/*=-1*/) ) { - if (*cmd == ';' || length >= BUFSIZE) return false; + // SERIAL_ECHOLNPGM(" length=: ",length); + // SERIAL_ECHOLNPGM(" index_r=: ", index_r); + // SERIAL_ECHOLNPGM(" index_w=: ", index_w); + if (*cmd == ';' || length >= BUFSIZE) return false; //这里的会导致主板一直选项idle(); strcpy(commands[index_w].buffer, cmd); commit_command(skip_ok OPTARG(HAS_MULTI_SERIAL, serial_ind)); return true; @@ -191,7 +198,13 @@ bool GCodeQueue::process_injected_command() { * Enqueue and return only when commands are actually enqueued. * Never call this from a G-code handler! */ -void GCodeQueue::enqueue_one_now(const char * const cmd) { while (!enqueue_one(cmd)) marlin.idle(); } +void GCodeQueue::enqueue_one_now(const char * const cmd) { + uint16_t count = 0; + while (!enqueue_one(cmd)) { + marlin.idle(); + if (count++ > 500) { SERIAL_ECHO_MSG("_full"); break; } + } +} void GCodeQueue::enqueue_one_now(FSTR_P const fcmd) { while (!enqueue_one(fcmd)) marlin.idle(); } /** @@ -216,6 +229,7 @@ bool GCodeQueue::enqueue_one(FSTR_P const fcmd) { void GCodeQueue::enqueue_now_P(PGM_P const pgcode) { size_t i = 0; PGM_P p = pgcode; + if (TERN0(CREALITY_RTS, ring_buffer.full())) return; // rock——20220815 for (;;) { char c; while ((c = pgm_read_byte(&p[i])) && c != '\n') i++; @@ -564,18 +578,40 @@ void GCodeQueue::get_serial_commands() { * always receives complete command-lines, they can go directly * into the main command queue. */ + uint16_t SD_ReadTimeout = 0; + bool SD_Card_status = true; + bool sd_printing_autopause = false; inline void GCodeQueue::get_sdcard_commands() { static uint8_t sd_input_state = PS_NORMAL; - // Get commands if there are more in the file - if (!card.isStillFetching()) return; + if (!card.isStillFetching() || !card.isSDCardInserted()) return; int sd_count = 0; - while (!ring_buffer.full() && !card.eof()) { + bool card_eof = card.eof(); + while (!ring_buffer.full() && !card.eof() && card.isSDCardInserted()) { const int16_t n = card.get(); - const bool card_eof = card.eof(); - if (n < 0 && !card_eof) { SERIAL_ERROR_MSG(STR_SD_ERR_READ); continue; } - + card_eof = card.eof(); + if (n < 0 && !card_eof) { + SERIAL_ERROR_MSG(STR_SD_ERR_READ); continue; + } + // if (n < 0 && !card_eof) { + // if (SD_ReadTimeout > 50) { + // if (SD_Card_status) { + // SERIAL_ERROR_MSG(STR_SD_ERR_READ); + // // SD Read Error Auto print pause; + // if (!sd_printing_autopause) { + // sd_printing_autopause = true; + // queue.inject_P(PSTR("M25")); + // } + // } + // SD_Card_status = false; + // SD_ReadTimeout = 0; + // break; + // } + // SD_ReadTimeout++; + // } + // else + // SD_ReadTimeout = 0; CommandLine &command = ring_buffer.commands[ring_buffer.index_w]; const char sd_char = (char)n; const bool is_eol = ISEOL(sd_char); @@ -602,10 +638,15 @@ void GCodeQueue::get_serial_commands() { TERN_(POWER_LOSS_RECOVERY, recovery.cmd_sdpos = card.getIndex()); } - if (card.eof()) card.fileHasFinished(); // Handle end of file reached + if (card.eof()) { + // Handle end of file reached + card.fileHasFinished(); + TERN_(CREALITY_RTS, RTS_FileHasFinished()); + } } - else + else { process_stream_char(sd_char, sd_input_state, command.buffer, sd_count); + } } } @@ -637,8 +678,7 @@ void GCodeQueue::exhaust() { * Get the next command in the queue, optionally log it to SD, then dispatch it */ void GCodeQueue::advance() { - - // Process immediate commands + // Process immediate commands //有立即执行的指令 if (process_injected_command_P() || process_injected_command()) return; // Return if the G-code buffer is empty diff --git a/Marlin/src/gcode/sd/M23.cpp b/Marlin/src/gcode/sd/M23.cpp index 5a7d450e09..1a551369eb 100644 --- a/Marlin/src/gcode/sd/M23.cpp +++ b/Marlin/src/gcode/sd/M23.cpp @@ -27,6 +27,9 @@ #include "../gcode.h" #include "../../sd/cardreader.h" #include "../../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif /** * M23: Select File @@ -44,6 +47,7 @@ void GcodeSuite::M23() { card.openFileRead(parser.string_arg); TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0)); + TERN_(CREALITY_RTS, RTS_OpenFileCloud()); } #endif // HAS_MEDIA diff --git a/Marlin/src/gcode/sd/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp index 6eb1375db4..6647f5e110 100644 --- a/Marlin/src/gcode/sd/M24_M25.cpp +++ b/Marlin/src/gcode/sd/M24_M25.cpp @@ -28,6 +28,9 @@ #include "../../sd/cardreader.h" #include "../../module/printcounter.h" #include "../../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(PARK_HEAD_ON_PAUSE) #include "../../feature/pause.h" @@ -86,6 +89,8 @@ void GcodeSuite::M24() { #endif ui.reset_status(); + + TERN_(CREALITY_RTS, RTS_PrintStartedSD()); } /** diff --git a/Marlin/src/gcode/temp/M104_M109.cpp b/Marlin/src/gcode/temp/M104_M109.cpp index d27ff75d39..45474fffda 100644 --- a/Marlin/src/gcode/temp/M104_M109.cpp +++ b/Marlin/src/gcode/temp/M104_M109.cpp @@ -38,6 +38,10 @@ #include "../../MarlinCore.h" // for startOrResumeJob, etc. +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) #include "../../module/printcounter.h" #if ENABLED(CANCEL_OBJECTS) @@ -110,6 +114,8 @@ void GcodeSuite::M104_M109(const bool isM109) { #endif thermalManager.setTargetHotend(temp, target_extruder); + TERN_(CREALITY_RTS, temphot = temp); + #if ENABLED(DUAL_X_CARRIAGE) if (idex_is_duplicating() && target_extruder == 0) thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index d1d4bfd0a6..cd4972fd68 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -96,11 +96,17 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; #endif #if HAS_MULTI_LANGUAGE + + #if ENABLED(CREALITY_RTS) + #include "rts/lcd_rts.h" + #endif + uint8_t MarlinUI::language; // Initialized by settings.load void MarlinUI::set_language(const uint8_t lang) { if (lang < NUM_LANGUAGES) { language = lang; TERN_(HAS_MARLINUI_U8GLIB, update_language_font()); + TERN_(CREALITY_RTS, rts.updateLanguageDisplay()); return_to_status(); refresh(); } diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 8ec25ab5c6..e4e9c0b098 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -223,6 +223,8 @@ public: #if HAS_MULTI_LANGUAGE static uint8_t language; static void set_language(const uint8_t lang); + #else + static constexpr uint8_t language = 0; #endif #if HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/sovol_rts/sovol_rts.cpp b/Marlin/src/lcd/sovol_rts/sovol_rts.cpp index 82a80bdd4a..0c5633b6f3 100644 --- a/Marlin/src/lcd/sovol_rts/sovol_rts.cpp +++ b/Marlin/src/lcd/sovol_rts/sovol_rts.cpp @@ -110,7 +110,6 @@ float axis_unit = 10; int16_t update_time_value = 0; bool poweroff_continue = false; -char commandbuf[30]; static SovolPage change_page_number = ID_Startup; diff --git a/Marlin/src/lcd/sovol_rts/sovol_rts.h b/Marlin/src/lcd/sovol_rts/sovol_rts.h index 15642e06c9..daeef239b0 100644 --- a/Marlin/src/lcd/sovol_rts/sovol_rts.h +++ b/Marlin/src/lcd/sovol_rts/sovol_rts.h @@ -381,8 +381,6 @@ extern void RTS_Init(); extern int16_t update_time_value; extern bool poweroff_continue; -extern bool sdcard_pause_check; -extern bool sd_printing_autopause; extern bool pause_flag; void RTS_AutoBedLevelPage(); diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 5b7be5d00c..46fdaeca2c 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -33,6 +33,8 @@ #if ENABLED(SOVOL_SV06_RTS) #include "../lcd/sovol_rts/sovol_rts.h" +#elif ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(FT_MOTION) @@ -235,6 +237,7 @@ void Endstops::enable(const bool onoff) { hit_on_purpose(); else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHome_L, ID_KillHome_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_202)); marlin.kill(GET_TEXT_F(MSG_KILL_HOMING_FAILED)); } } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 1012cc4150..e323d4332c 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -35,7 +35,10 @@ #if IS_SCARA #include "../libs/buzzer.h" - #include "../lcd/marlinui.h" +#endif + +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(POLAR) @@ -2220,6 +2223,14 @@ void prepare_line_to_destination() { DEBUG_ECHOLNPGM(")"); } + #if ENABLED(PROBE_ACTIVATION_SWITCH) + if (axis == Z_AXIS && HIGH == READ(PROBE_ACTIVATION_SWITCH_PIN)) { + WRITE(PROBE_TARE_PIN, LOW); + delay(200); + WRITE(PROBE_TARE_PIN, HIGH); + } + #endif + // Only do some things when moving towards an endstop const int8_t axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) ? TOOL_X_HOME_DIR(active_extruder) : home_dir(axis); @@ -2279,13 +2290,12 @@ void prepare_line_to_destination() { planner.synchronize(); if (is_home_dir) { + endstops.validate_homing_move(); #if HOMING_Z_WITH_PROBE && HAS_QUIET_PROBING if (axis == Z_AXIS && final_approach) probe.set_devices_paused_for_probing(false); #endif - endstops.validate_homing_move(); - // Re-enable stealthChop if used. Disable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) end_sensorless_homing_per_axis(axis, stealth_states); @@ -2459,6 +2469,7 @@ void prepare_line_to_destination() { #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_STATE) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) #define _ANDCANT(N) && !_CAN_HOME(N) if (true MAIN_AXIS_MAP(_ANDCANT)) return; + #undef _CAN_HOME #endif if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> homeaxis(", C(AXIS_CHAR(axis)), ")"); @@ -2757,6 +2768,8 @@ void prepare_line_to_destination() { destination[axis] = current_position[axis]; + //if (axis == Z_AXIS) current_position.z -= probe.offset.z; //rock_20220801 手动对高功能。 + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); #endif @@ -2847,7 +2860,32 @@ void set_axis_is_at_home(const AxisEnum axis) { /** * Z Probe Z Homing? Account for the probe's Z offset. */ - #if HAS_BED_PROBE && Z_HOME_TO_MIN + #if 0 + #if HAS_BED_PROBE && Z_HOME_TO_MAX // Z_HOME_TO_MIN Rock_20220827 + if (axis == Z_AXIS) { + #if HOMING_Z_WITH_PROBE + + SERIAL_ECHOLNPGM(" current_position.z_old=: ", current_position.z); + current_position.z -= probe.offset.z; + SERIAL_ECHOLNPGM(" probe.offset.z=: ", probe.offset.z); + SERIAL_ECHOLNPGM(" current_position.z_new=: ", current_position.z); + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***\n> probe.offset.z = ", probe.offset.z); + + #else + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z HOMED TO ENDSTOP ***"); + + #endif + } + #endif + + #if ENABLED(BLTOUCH_AND_Z_LIMIT) // 正方向回原点进行Z轴补偿 + if (axis == Z_AXIS) current_position.z -= probe.offset.z; + #endif + #endif + + #if HAS_BED_PROBE && Z_HOME_DIR < 0 if (axis == Z_AXIS) { #if HOMING_Z_WITH_PROBE #if ENABLED(BD_SENSOR) @@ -2861,6 +2899,15 @@ void set_axis_is_at_home(const AxisEnum axis) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z homed to ENDSTOP ***"); #endif } + #elif HAS_BED_PROBE && Z_HOME_DIR > 0 // Return to the origin in the positive direction for Z-axis compensation + if (axis == Z_AXIS) { + #if ALL(CREALITY_RTS, BLTOUCH, HOMING_Z_WITH_PROBE) && Z_HOME_DIR > 0 + if (st_bedNozzleHeightCal.bedNozzleHeightCalFinishFlag) + current_position.z -= probe.offset.z + st_bedNozzleHeightCal.zCoordinateOffset; + #else + //current_position.z -= probe.offset.z; + #endif + } #endif TERN_(I2C_POSITION_ENCODERS, I2CPEM.homed(axis)); @@ -2886,3 +2933,555 @@ void set_axis_is_at_home(const AxisEnum axis) { home_offset[axis] = v; } #endif + +#if ENABLED(CREALITY_RTS) + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + + float homeaxis_bl(const AxisEnum axis, const feedRate_t fr_mm_fast, const feedRate_t fr_mm_slow) { + float coordinateOffset = VALUE_INVALID_8BIT; + + #if ANY(MORGAN_SCARA, MP_SCARA) + // Only Z homing (with probe) is permitted + if (axis != Z_AXIS) { BUZZ(100, 880); return; } + #else + #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_ENDSTOP) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) + if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return 0xFFFF; + #undef _CAN_HOME + #endif + + if (ENABLED(USER_LEVEL_DEBUG)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl start current_position.z * 100 = ", current_position.z * 100); + DEBUG_ECHOLNPGM(">>> homeaxis(", axis_codes[axis], ")"); + } + + // const int axis_home_dir = -TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + // ? x_home_dir(active_extruder) : home_dir(axis); + //由于此时使用了最大限位开关,Z_HOME_DIR被设置成1,不能用上面的判断,所以此处强制赋值为-1 + const int axis_home_dir = -1; + + // Homing Z towards the bed? Deploy the Z probe or endstop. + if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.deploy())) // 弹出bltouch + return VALUE_INVALID_8BIT; + + // Set flags for X, Y, Z motor locking + #if HAS_EXTRA_ENDSTOPS + switch (axis) { + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); + default: break; + } + #endif + + // Fast move towards endstop until triggered + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Home 1 Fast:"); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS && bltouch.deploy()) return VALUE_INVALID_8BIT; // The initial DEPLOY + #endif + + #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) + const xy_float_t backoff = SENSORLESS_BACKOFF_MM; + if (((ENABLED(X_SENSORLESS) && axis == X_AXIS) || (ENABLED(Y_SENSORLESS) && axis == Y_AXIS)) && backoff[axis]) + do_homing_move(axis, -ABS(backoff[axis]) * axis_home_dir, homing_feedrate(axis)); + #endif + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl start to move z * 100 = ", axis * 100, + "\nhomeaxis_bl current scalin * 100 = ", (int)(max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir * 100), + ); + + abce_pos_t target1 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target1[axis] * 100 = ", target1[axis] * 100); + + do_homing_move(axis, 0.90f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(fr_mm_fast)); + // do_homing_move(axis, 1.5f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir);//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target2 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target2[axis] * 100 = ", target2[axis] * 100); + + // 获取z轴两坐标系的差值 + #if ANY(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(target2[axis] + target1[axis]); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(target2[axis] + target1[axis]); + #endif + coordinateOffset = target2[axis] + target1[axis]; + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-1 Fast: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-1 Fast: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + abce_pos_t target3 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target3[axis] * 100 = ", target3[axis] * 100); + + //do_homing_move(axis, 0.75f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST * 15)); + do_homing_move(axis, 0.25f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(fr_mm_slow));//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target4 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target4[axis] * 100 = ", target4[axis] * 100); + + // 获取z轴两坐标系的差值 + #if ENABLED(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(rts.GetzCoordinateOffset() + /*target3[axis] + */target4[axis]); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(gLcdSermoonV2UI.GetzCoordinateOffset() + /*target3[axis] + */target4[axis]); + #endif + coordinateOffset += target4[axis]; + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-2 Fast: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100, " coordinateOffset * 100 = ", coordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-2 Fast: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,此时的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z] * 100 = ", current_position[axis] * 100); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) + #endif + + // When homing Z with probe respect probe clearance + const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS)); + const float bump = axis_home_dir * ( + use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis) + ); + + // If a second homing move is configured... + if (bump) { + // Move away from the endstop by the axis HOMING_BUMP_MM + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Move Away:"); + do_homing_move(axis, -bump + #if HOMING_Z_WITH_PROBE + , MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_FEEDRATE_FAST : 0) + #endif + ); + + #if ENABLED(DETECT_BROKEN_ENDSTOP) + // Check for a broken endstop + EndstopEnum es; + switch (axis) { + default: + case X_AXIS: es = X_ENDSTOP; break; + case Y_AXIS: es = Y_ENDSTOP; break; + case Z_AXIS: es = Z_ENDSTOP; break; + } + if (TEST(endstops.state(), es)) { + SERIAL_ECHO_MSG("Bad ", axis_codes[axis], " Endstop?"); + kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); + } + #endif + + // Slow move towards endstop until triggered + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Home 2 Slow:"); //第二次测量 + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE) + #endif + + abce_pos_t target5 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target5[axis] * 100 = ", target5[axis] * 100); + + do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); + + abce_pos_t target6 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target6[axis] * 100 = ", target6[axis] * 100); + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,此时的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z_2 * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z]_2 * 100 = ", current_position[axis] * 100); + + // 第二次测量值 + #if ENABLED(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(rts.GetzCoordinateOffset() - (target5[axis] + target6[axis])); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(gLcdSermoonV2UI.GetzCoordinateOffset() - (target5[axis] + target6[axis])); + #endif + coordinateOffset -= (target5[axis] + target6[axis]); + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 2 Slow: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100, + "\nhomeaxis_bl Home 2 Slow: coordinateOffset * 100 = ", coordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 2 Slow: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS) bltouch.stow(); // The final STOW + #endif + } + + #if HAS_EXTRA_ENDSTOPS + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const float adj = ABS(endstops.x2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_x_lock(false); + stepper.set_x2_lock(false); + } + } + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const float adj = ABS(endstops.y2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_y_lock(false); + stepper.set_y2_lock(false); + } + } + #endif + + // Reset flags for X, Y, Z motor locking + switch (axis) { + default: break; + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(false); + } + #endif + + #ifdef TMC_HOME_PHASE + // move back to homing phase if configured and capable + backout_to_tmc_homing_phase(axis); + #endif + + #if IS_SCARA + + set_axis_is_at_home(axis); + sync_plan_position(); + + #elif ENABLED(DELTA) + + // Delta has already moved all three towers up in G28 + // so here it re-homes each tower in turn. + // Delta homing treats the axes as normal linear axes. + + const float adjDistance = delta_endstop_adj[axis], + minDistance = (MIN_STEPS_PER_SEGMENT) * planner.mm_per_step[axis]; + + // Retrace by the amount specified in delta_endstop_adj if more than min steps. + if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("adjDistance:", adjDistance); + do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); + } + + #else // CARTESIAN / CORE / MARKFORGED_XY + + //set_axis_is_at_home(axis); + sync_plan_position(); + + destination[axis] = current_position[axis]; + + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + + #endif + + // Put away the Z probe + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && probe.stow()) return VALUE_INVALID_8BIT; + #endif + + #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) + const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; + if (endstop_backoff[axis]) { + current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; + line_to_current_position( + #if HOMING_Z_WITH_PROBE + (axis == Z_AXIS) ? MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST) : + #endif + homing_feedrate(axis) + ); + + #if ENABLED(SENSORLESS_HOMING) + planner.synchronize(); + if (false + #if ANY(IS_CORE, MARKFORGED_XY) + || axis != NORMAL_AXIS + #endif + ) safe_delay(200); // Short delay to allow belts to spring back + #endif + } + #endif + + // Clear retracted status if homing the Z axis + TERN_(FWRETRACT, if (axis == Z_AXIS) fwretract.current_hop = 0.0); + + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl end current_position.z * 100 = ", current_position.z * 100); + SERIAL_EOL(); + } + return coordinateOffset; + } + + #else // !BLTOUCH_AND_Z_LIMIT + + void homeaxis_bl(const AxisEnum axis) { + + #if IS_SCARA + // Only Z homing (with probe) is permitted + if (axis != Z_AXIS) { BUZZ(100, 880); return; } + #else + #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_ENDSTOP) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) + if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return; + #endif + + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOLNPGM("\nhomeaxis_bl start current_position.z * 100 = ", current_position.z * 100); + DEBUG_ECHOLNPGM(">>> homeaxis(", axis_codes[axis], ")"); + } + + // const int axis_home_dir = -TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + // ? x_home_dir(active_extruder) : home_dir(axis); + //由于此时使用了最大限位开关,Z_HOME_DIR被设置成1,不能用上面的判断,所以此处强制赋值为-1 + const int axis_home_dir = -1; + + // Homing Z towards the bed? Deploy the Z probe or endstop. + if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.deploy())) // 弹出bltouch + return; + + // Set flags for X, Y, Z motor locking + #if HAS_EXTRA_ENDSTOPS + switch (axis) { + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); + default: break; + } + #endif + + // Fast move towards endstop until triggered + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 1 Fast:"); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS && bltouch.deploy()) return; // The initial DEPLOY + #endif + + #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) + const xy_float_t backoff = SENSORLESS_BACKOFF_MM; + if (((ENABLED(X_SENSORLESS) && axis == X_AXIS) || (ENABLED(Y_SENSORLESS) && axis == Y_AXIS)) && backoff[axis]) + do_homing_move(axis, -ABS(backoff[axis]) * axis_home_dir, homing_feedrate(axis)); + #endif + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl start to move z * 100 = ", axis * 100, + "\nhomeaxis_bl current scalin * 100 = ", (int)(max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir * 100), + ); + } + + abce_pos_t target1 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target1[axis] * 100 = ", target1[axis] * 100); + + do_homing_move(axis, 1.5f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir);//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target2 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target2[axis] * 100 = ", target2[axis] * 100); + + #if ENABLED(CREALITY_RTS) + // 获取z轴两坐标系的差值 + // 这里的“+probe.offset.z”,是因为执行了G28后,Z轴会走一段路程,其长度为probe.offset.z ,这也是实现下限位必须走的距离 + // gLcdSermoonV2UI.setZCoordinateOffset(target2[axis] + target1[axis] + gLcdSermoonV2UI.GetzCoordinateOffset() + probe.offset.z); + // st_bedNozzleHeightCal.zCoordinateOffset=target2[axis] + target1[axis] + st_bedNozzleHeightCal.zCoordinateOffset+probe.offset.z; + st_bedNozzleHeightCal.zCoordinateOffset=target2[axis] + target1[axis]; + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl zCoordinateOffset * 100 = ", st_bedNozzleHeightCal.zCoordinateOffset * 100); + SERIAL_EOL(); + } + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,测试的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + #endif + + #if HOMING_Z_WITH_PROBE + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z] * 100 = ", current_position[axis] * 100); + } + #endif + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) + #endif + + // When homing Z with probe respect probe clearance + const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS)); + const float bump = axis_home_dir * ( + use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis) + ); + + // If a second homing move is configured... + if (bump) { + // Move away from the endstop by the axis HOMING_BUMP_MM + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:"); + do_homing_move(axis, -bump + OPTARG(HOMING_Z_WITH_PROBE, MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_FEEDRATE_FAST : 0)) + ); + + #if ENABLED(DETECT_BROKEN_ENDSTOP) + // Check for a broken endstop + EndstopEnum es; + switch (axis) { + default: + case X_AXIS: es = X_ENDSTOP; break; + case Y_AXIS: es = Y_ENDSTOP; break; + case Z_AXIS: es = Z_ENDSTOP; break; + } + if (TEST(endstops.state(), es)) { + SERIAL_ECHO_MSG("Bad ", axis_codes[axis], " Endstop?"); + kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); + } + #endif + + // Slow move towards endstop until triggered + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 2 Slow:"); //第二次测量 + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE) + #endif + + do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS) bltouch.stow(); // The final STOW + #endif + } + + #if HAS_EXTRA_ENDSTOPS + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const float adj = ABS(endstops.x2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_x_lock(false); + stepper.set_x2_lock(false); + } + } + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const float adj = ABS(endstops.y2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_y_lock(false); + stepper.set_y2_lock(false); + } + } + #endif + + // Reset flags for X, Y, Z motor locking + switch (axis) { + default: break; + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(false); + } + #endif + + #ifdef TMC_HOME_PHASE + // move back to homing phase if configured and capable + backout_to_tmc_homing_phase(axis); + #endif + + #if IS_SCARA + + set_axis_is_at_home(axis); + sync_plan_position(); + + #elif ENABLED(DELTA) + + // Delta has already moved all three towers up in G28 + // so here it re-homes each tower in turn. + // Delta homing treats the axes as normal linear axes. + + const float adjDistance = delta_endstop_adj[axis], + minDistance = (MIN_STEPS_PER_SEGMENT) * planner.mm_per_step[axis]; + + // Retrace by the amount specified in delta_endstop_adj if more than min steps. + if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("adjDistance:", adjDistance); + do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); + } + + #else // CARTESIAN / CORE / MARKFORGED_XY + + //set_axis_is_at_home(axis); + sync_plan_position(); + + destination[axis] = current_position[axis]; + + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + + #endif + + // Put away the Z probe + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && probe.stow()) return; + #endif + + #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) + const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; + if (endstop_backoff[axis]) { + current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; + line_to_current_position(TERN_(HOMING_Z_WITH_PROBE, axis == Z_AXIS ? MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST) :) homing_feedrate(axis)); + + #if ENABLED(SENSORLESS_HOMING) + planner.synchronize(); + if (false + #if ANY(IS_CORE, MARKFORGED_XY) + || axis != NORMAL_AXIS + #endif + ) safe_delay(200); // Short delay to allow belts to spring back + #endif + } + #endif + + // Clear retracted status if homing the Z axis + #if ENABLED(FWRETRACT) + if (axis == Z_AXIS) fwretract.current_hop = 0.0; + #endif + + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl end current_position.z * 100 = ", current_position.z * 100); + SERIAL_EOL(); + } + } + + #endif // !BLTOUCH_AND_Z_LIMIT +#endif // CREALITY_RTS diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 8050e66448..819def342e 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -74,6 +74,10 @@ extern xyz_pos_t cartes; constexpr feedRate_t z_probe_fast_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST); #endif +#if ENABLED(Z_SAFE_HOMING) + constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; +#endif + /** * Feed rates are often configured with mm/m * but the planner and stepper like mm/s units. @@ -455,6 +459,13 @@ void set_axis_is_at_home(const AxisEnum axis); */ extern main_axes_bits_t axes_homed, axes_trusted; void homeaxis(const AxisEnum axis); + #if ENABLED(CREALITY_RTS) + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + float homeaxis_bl(const AxisEnum axis, const feedRate_t fr_mm_fast=Z_PROBE_FEEDRATE_FAST, const feedRate_t fr_mm_slow=Z_PROBE_FEEDRATE_SLOW); + #else + void homeaxis_bl(const AxisEnum axis); + #endif + #endif void set_axis_never_homed(const AxisEnum axis); main_axes_bits_t axes_should_home(main_axes_bits_t axes_mask=main_axes_mask); bool homing_needed_error(main_axes_bits_t axes_mask=main_axes_mask); diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 3a8bb2b6c6..6ce9d85c69 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -37,6 +37,9 @@ #include "../gcode/gcode.h" #include "../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif #if HAS_LEVELING #include "../feature/bedlevel/bedlevel.h" @@ -1060,6 +1063,7 @@ float Probe::probe_at_point( // The user may want to quickly move the carriage or bed by hand to avoid bed damage from the (hot) nozzle. // This would also benefit from the contemplated "Audio Alerts" feature. stow(); + TERN_(CREALITY_RTS, RTS_ProbingFailed()); LCD_MESSAGE(MSG_LCD_PROBING_FAILED); #if DISABLED(G29_RETRY_AND_RECOVER) SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED); diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index f0ade99082..8864c38950 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -51,6 +51,10 @@ #include "stepper.h" #include "temperature.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../lcd/marlinui.h" #include "../libs/vector_3.h" // for matrix_3x3 #include "../gcode/gcode.h" @@ -711,6 +715,17 @@ typedef struct SettingsDataStruct { char gcode_macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1]; #endif + // + // Creality RTS + // + #if ENABLED(CREALITY_RTS) + bool wifi_enable_flag; // M194 S + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + float zCoordinateOffset; // RTS Z offset + #endif + float bedNozzleHeightCalZ; + #endif + } SettingsData; //static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!"); @@ -1765,6 +1780,15 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(ui.language); #endif + #if ENABLED(CREALITY_RTS) + _FIELD_TEST(wifi_enable_flag); + EEPROM_WRITE(wifi_enable_flag); + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + EEPROM_WRITE(rts.zCoordinateOffset); // Z轴空间坐标差 + #endif + EEPROM_WRITE(bedNozzleHeightCalZ); // caixiaoliang add 20210807 + #endif + // // Model predictive control // @@ -2900,6 +2924,13 @@ void MarlinSettings::postprocess() { } #endif + #if ENABLED(CREALITY_RTS) + _FIELD_TEST(wifi_enable_flag); + EEPROM_READ(wifi_enable_flag); + EEPROM_READ(rts.zCoordinateOffset); // rock_20220730 + EEPROM_READ(bedNozzleHeightCalZ); // caixiaoliang add 20210807 + #endif + // // Model predictive control // @@ -3690,6 +3721,11 @@ void MarlinSettings::reset() { stepper.set_digipot_current(q, tmp_motor_current_setting[q]); #endif + #if ENABLED(CREALITY_RTS) + ui.language = 1; // 0:Chinese, 1:English + wifi_enable_flag = true; + #endif + // // Adaptive Step Smoothing state // @@ -4185,6 +4221,12 @@ void MarlinSettings::reset() { // MMU3 // TERN_(HAS_PRUSA_MMU3, gcode.MMU3_report(forReplay)); + + #if ENABLED(CREALITY_RTS) + CONFIG_ECHO_HEADING("WIFI Enabled"); + CONFIG_ECHO_MSG(" M194 S", wifi_enable_flag); + //SERIAL_ECHOLNPGM(" rts.zCoordinateOffset ! ", rts.zCoordinateOffset); + #endif } #endif // !DISABLE_M503 diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index f0ca49ef66..d82cfe2b3a 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -54,6 +54,8 @@ #include "../lcd/dwin/creality/dwin.h" #elif ENABLED(SOVOL_SV06_RTS) #include "../lcd/sovol_rts/sovol_rts.h" +#elif ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(EXTENSIBLE_UI) @@ -701,7 +703,7 @@ volatile bool Temperature::raw_temps_ready = false; TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Run UI update - #if ENABLED(SOVOL_SV06_RTS) + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) RTS_Update(); #else ui.update(); @@ -789,7 +791,8 @@ void Temperature::factory_reset() { int cycles = 0; bool heating = true; - millis_t next_temp_ms = millis(), t1 = next_temp_ms, t2 = next_temp_ms; + millis_t next_temp_ms, t1, t2; + next_temp_ms = t1 = t2 = millis(); long t_high = 0, t_low = 0; raw_pid_t tune_pid = { 0, 0, 0 }; @@ -950,11 +953,13 @@ void Temperature::factory_reset() { } else if (ELAPSED(ms, temp_change_ms)) { // Watch timer expired TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); _TEMP_ERROR(heater_id, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, current_temp); } } else if (current_temp < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) { // Heated, then temperature fell too far? TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillRunaway_L, ID_KillRunaway_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_ERR_THERMAL_RUNAWAY, current_temp); } } @@ -970,6 +975,7 @@ void Temperature::factory_reset() { TERN_(EXTENSIBLE_UI, ExtUI::onPIDTuning(ExtUI::pidresult_t::PID_TUNING_TIMEOUT)); TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT))); TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); SERIAL_ECHOPGM(STR_PID_AUTOTUNE); SERIAL_ECHOLNPGM(STR_PID_TIMEOUT); break; } @@ -1677,6 +1683,7 @@ void Temperature::_temp_error( void Temperature::maxtemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_HOTEND || HAS_HEATED_BED TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_11 : Error_08)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(1)); TERN_(EXTENSIBLE_UI, ExtUI::onMaxTempError(heater_id)); #endif @@ -1693,6 +1700,7 @@ void Temperature::maxtemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_HOTEND || HAS_HEATED_BED TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_11 : Error_08)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onMinTempError(heater_id)); #endif @@ -1925,6 +1933,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T const auto deg = degHotend(e); if (deg > temp_range[e].maxtemp) { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_08)); MAXTEMP_ERROR(e, deg); } } @@ -1948,6 +1957,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T start_watching_hotend(e); // If temp reached, turn off elapsed check else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_07)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(e)); _TEMP_ERROR(e, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, temp); @@ -1974,6 +1984,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T const auto deg = degBed(); if (deg > BED_MAXTEMP) { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_08)); MAXTEMP_ERROR(H_BED, deg); } } @@ -1988,6 +1999,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T start_watching_bed(); // If temp reached, turn off elapsed check else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_10)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(H_BED)); _TEMP_ERROR(H_BED, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, deg); @@ -3446,6 +3458,7 @@ void Temperature::init() { case TRRunaway: TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillRunaway_L, ID_KillRunaway_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_09 : Error_06)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(heater_id)); _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_ERR_THERMAL_RUNAWAY, current); @@ -3454,6 +3467,7 @@ void Temperature::init() { #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) case TRMalfunction: TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_09 : Error_06)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(heater_id)); _TEMP_ERROR(heater_id, F(STR_T_THERMAL_MALFUNCTION), MSG_ERR_TEMP_MALFUNCTION, current); break; @@ -4498,9 +4512,25 @@ void Temperature::isr() { #if HAS_TEMP_HOTEND print_heater_state(H_NONE, degHotend(target_extruder), degTargetHotend(target_extruder) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(target_extruder))); #endif + #if HAS_HEATED_BED - print_heater_state(H_BED, degBed(), degTargetBed() OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #if ENABLED(BED_TEMP_COMP) + celsius_float_t bedDisp = degBed(); + celsius_float_t bedTargetDisp = degTargetBed(); + if (degTargetBed() > 65 && degTargetBed() <= 86) { + bedDisp -= (5 * bedDisp) / degTargetBed(); + bedTargetDisp -= 5; + } + else if (degTargetBed() > 86 && degTargetBed() <= 127) { + bedDisp -= (7 * bedDisp) / degTargetBed(); + bedTargetDisp -= 7; + } + print_heater_state(H_BED, bedDisp, bedTargetDisp OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #else + print_heater_state(H_BED, degBed(), degTargetBed() OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #endif #endif + #if HAS_TEMP_CHAMBER print_heater_state(H_CHAMBER, degChamber(), TERN0(HAS_HEATED_CHAMBER, degTargetChamber()) OPTARG(SHOW_TEMP_ADC_VALUES, rawChamberTemp())); #endif @@ -4522,7 +4552,7 @@ void Temperature::isr() { #if HAS_MULTI_HOTEND HOTEND_LOOP() print_heater_state((heater_id_t)e, degHotend(e), degTargetHotend(e) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(e))); #endif - SString<100> s(F(" @:"), getHeaterPower((heater_id_t)target_extruder)); + SString<120> s(F(" @:"), getHeaterPower((heater_id_t)target_extruder)); TERN_(HAS_HEATED_BED, s.append(F(" B@:"), getHeaterPower(H_BED))); TERN_(PELTIER_BED, s.append(F(" P@:"), temp_bed.peltier_dir_heating ? 'H' : 'C')); TERN_(HAS_HEATED_CHAMBER, s.append(F(" C@:"), getHeaterPower(H_CHAMBER))); @@ -4530,6 +4560,10 @@ void Temperature::isr() { #if HAS_MULTI_HOTEND HOTEND_LOOP() s.append(F(" @"), e, ':', getHeaterPower((heater_id_t)e)); #endif + #if ENABLED(CREALITY_CLOUD) + TERN_(HAS_FAN0, s.append(F(" FAN0@:"), thermalManager.fan_speed[0])); + TERN_(HAS_FAN1, s.append(F(" FAN1@:"), thermalManager.fan_speed[1])); + #endif s.echo(); } @@ -4573,6 +4607,7 @@ void Temperature::isr() { #define MIN_COOLING_SLOPE_TIME 60 #endif + //static int s_cnt = 0; bool Temperature::wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling/*=true*/ OPTARG(G26_CLICK_CAN_CANCEL, const bool click_to_cancel/*=false*/) ) { @@ -4604,6 +4639,7 @@ void Temperature::isr() { millis_t now, next_temp_ms = 0, cool_check_ms = 0; for (marlin.heatup_start(); marlin.is_heating() && TEMP_CONDITIONS; ) { // Target temperature might be changed during the loop + //if (!(++s_cnt % 200)) SERIAL_ECHOLN("wait_for_hotend"); if (target_temp != degTargetHotend(target_extruder)) { wants_to_cool = isCoolingHotend(target_extruder); target_temp = degTargetHotend(target_extruder); @@ -4687,6 +4723,8 @@ void Temperature::isr() { update_time_value = RTS_UPDATE_VALUE; if (card.isStillPrinting()) rts.refreshTime(); rts.start_print_flag = false; + #elif ENABLED(CREALITY_RTS) + update_time_value = RTS_UPDATE_VALUE; #else ui.reset_status(); #endif @@ -4798,6 +4836,7 @@ void Temperature::isr() { millis_t now, next_temp_ms = 0, cool_check_ms = 0; marlin.heatup_start(); do { + //if (!(++s_cnt % 200)) SERIAL_ECHOLN("wait_for_bed"); // Target temperature might be changed during the loop if (target_temp != degTargetBed()) { wants_to_cool = isCoolingBed(); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 426437d9d1..8a41043412 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -41,6 +41,10 @@ #include "../lcd/sovol_rts/sovol_rts.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../module/planner.h" // for synchronize #include "../module/printcounter.h" #include "../gcode/queue.h" @@ -485,6 +489,7 @@ void CardReader::printSelectedFilename() { } void CardReader::mount() { + delay(5); flag.mounted = false; nrItems = -1; if (root.isOpen()) root.close(); @@ -1665,6 +1670,8 @@ void CardReader::fileHasFinished() { flag.sdprintdone = true; // Stop getting bytes from the SD card marlin.setState(MF_SD_COMPLETE); // Tell Marlin to enqueue M1001 soon + + TERN_(CREALITY_RTS, RTS_SDFileCompleted()); } #if ENABLED(AUTO_REPORT_SD_STATUS) diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp index fde697c1f4..b1ba710932 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp @@ -22,6 +22,10 @@ #include "../../inc/MarlinConfigPre.h" +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../feature/powerloss.h" +#endif + /** * Adjust USB_DEBUG to select debugging verbosity. * 0 - no debug messages @@ -229,7 +233,16 @@ void DiskIODriver_USBFlash::idle() { } break; - case MEDIA_READY: break; + case MEDIA_READY: + #if ENABLED(POWER_LOSS_RECOVERY) + static bool firstStart = false; + if (!firstStart) { + firstStart = true; + recovery.check(); + } + #endif + break; + case MEDIA_ERROR: break; } From f7aa6abe076af3ce4c0e826fb299ec050f8e68bb Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 6 May 2025 22:25:57 -0500 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=85=20Ender-5=20S1=20CI=20Test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-build-tests.yml | 1 + buildroot/tests/STM32F401RE_creality | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100755 buildroot/tests/STM32F401RE_creality diff --git a/.github/workflows/ci-build-tests.yml b/.github/workflows/ci-build-tests.yml index 5d53536a27..802b6248d3 100644 --- a/.github/workflows/ci-build-tests.yml +++ b/.github/workflows/ci-build-tests.yml @@ -124,6 +124,7 @@ jobs: - Opulo_Lumen_REV3 - rumba32 - STM32F401RC_creality + - STM32F401RE_creality - STM32F407VE_black - I3DBEEZ9_V1 diff --git a/buildroot/tests/STM32F401RE_creality b/buildroot/tests/STM32F401RE_creality new file mode 100755 index 0000000000..b3c5c24e99 --- /dev/null +++ b/buildroot/tests/STM32F401RE_creality @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# +# Build tests for STM32F401RE_creality +# + +# exit on first failure +set -e + +use_example_configs "Creality/Ender-5 S1" +exec_test $1 $2 "Ender-5 S1" "$3" + +# clean up +restore_configs