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/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 31d3b8364b..35edc29369 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/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/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/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp
index dabb53b47b..2ce0a5b331 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/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..4d620155bc 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.
@@ -1276,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/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/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/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/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/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/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/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/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 5943b513e7..5bbe0c3d8d 100644
--- a/Marlin/src/inc/Conditionals-4-adv.h
+++ b/Marlin/src/inc/Conditionals-4-adv.h
@@ -1075,7 +1075,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 b9eeb3d85a..4f10126314 100644
--- a/Marlin/src/inc/Conditionals-5-post.h
+++ b/Marlin/src/inc/Conditionals-5-post.h
@@ -3178,7 +3178,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)
@@ -3328,7 +3328,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
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/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/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 8a92482d82..ebab4ea668 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;
}
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
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 = + - -
+
+
+
+ +
+ +
+
+
+