From 5abc421e40db0ec363d41b98cd23950d2b3a4b97 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 6 May 2025 22:25:36 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Ender-5=20S1=20modified=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/MarlinCore.cpp | 62 +- Marlin/src/feature/pause.cpp | 70 +- Marlin/src/feature/powerloss.cpp | 85 ++- Marlin/src/feature/powerloss.h | 4 + Marlin/src/feature/runout.cpp | 7 + Marlin/src/gcode/bedlevel/abl/G29.cpp | 179 ++++++ Marlin/src/gcode/calibrate/G28.cpp | 14 + Marlin/src/gcode/config/M220.cpp | 4 + Marlin/src/gcode/control/M80_M81.cpp | 6 + Marlin/src/gcode/gcode.cpp | 2 +- Marlin/src/gcode/host/M115.cpp | 21 +- Marlin/src/gcode/lcd/M0_M1.cpp | 6 + Marlin/src/gcode/motion/G0_G1.cpp | 7 +- Marlin/src/gcode/ota/M936.cpp | 16 +- Marlin/src/gcode/queue.cpp | 64 +- Marlin/src/gcode/sd/M23.cpp | 4 + Marlin/src/gcode/sd/M24_M25.cpp | 5 + Marlin/src/gcode/temp/M104_M109.cpp | 6 + Marlin/src/lcd/marlinui.cpp | 6 + Marlin/src/lcd/marlinui.h | 2 + Marlin/src/lcd/sovol_rts/sovol_rts.cpp | 1 - Marlin/src/lcd/sovol_rts/sovol_rts.h | 2 - Marlin/src/module/endstops.cpp | 3 + Marlin/src/module/motion.cpp | 607 +++++++++++++++++- Marlin/src/module/motion.h | 11 + Marlin/src/module/probe.cpp | 4 + Marlin/src/module/settings.cpp | 42 ++ Marlin/src/module/temperature.cpp | 47 +- Marlin/src/sd/cardreader.cpp | 7 + .../sd/usb_flashdrive/Sd2Card_FlashDrive.cpp | 15 +- 30 files changed, 1249 insertions(+), 60 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 6d672e3b8c..54fb48ee57 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -30,6 +30,9 @@ #include "MarlinCore.h" +#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE) +#include "core/debug_out.h" + #include "HAL/shared/Delay.h" #include "HAL/shared/esp_wifi.h" #include "HAL/shared/cpu_exception/exception_hook.h" @@ -84,6 +87,10 @@ #endif #endif +#if ENABLED(CREALITY_RTS) + #include "lcd/rts/lcd_rts.h" +#endif + #if HAS_ETHERNET #include "feature/ethernet.h" #endif @@ -397,7 +404,11 @@ void Marlin::startOrResumeJob() { TERN_(POWER_LOSS_RECOVERY, recovery.purge()); #ifdef EVENT_GCODE_SD_ABORT - queue.inject(F(EVENT_GCODE_SD_ABORT)); + DEBUG_ECHOLNPGM("abortSDPrinting"); + //queue.inject(F(EVENT_GCODE_SD_ABORT)); + queue.enqueue_now(F(EVENT_GCODE_SD_ABORT)); + report_current_position(); + TERN_(CREALITY_RTS, RTS_UpdatePosition()); #endif TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine()); @@ -442,7 +453,7 @@ void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) { if (gcode.stepper_max_timed_out(ms)) { SERIAL_ERROR_START(); SERIAL_ECHOLN(F(STR_KILL_PRE), F(STR_KILL_INACTIVE_TIME), parser.command_ptr); - kill(); + TERN(CREALITY_RTS, RTS_StepperTimeout(), kill()); } const bool has_blocks = planner.has_blocks_queued(); // Any moves in the planner? @@ -473,8 +484,10 @@ void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) { TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled()); } } - else + else { + // if (!parked_or_ignoring && gcode.stepper_inactive_timeout() && !card.isPrinting() && !card.isPaused()) // rock_20220815 already_shutdown_steppers = false; + } } #endif @@ -832,7 +845,10 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { #endif // Handle SD Card insert / remove - TERN_(HAS_MEDIA, card.manage_media()); + #if HAS_MEDIA + if (TERN1(CREALITY_RTS, !HMI_lcd_flag.home_flag && !G29_flag)) // Avoid the problem of leveling and returning to zero, plugging and unplugging the card will affect the probe and report error 203 + card.manage_media(); + #endif // Announce Host Keepalive state (if any) TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive()); @@ -844,12 +860,16 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { TERN_(HAS_BEEPER, buzzer.tick()); // Handle UI input / draw events - #if ENABLED(SOVOL_SV06_RTS) + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) RTS_Update(); #else ui.update(); #endif + #if ENABLED(PROBE_ACTIVATION_SWITCH) + endstops.enable_z_probe(TERN1(CREALITY_RTS, (HMI_lcd_flag.home_flag || G29_flag)) && (LOW == READ(PROBE_ACTIVATION_SWITCH_PIN))); + #endif + // Run i2c Position Encoders #if ENABLED(I2C_POSITION_ENCODERS) { @@ -893,6 +913,22 @@ void Marlin::idle(const bool no_stepper_sleep/*=false*/) { // Direct Stepping TERN_(DIRECT_STEPPING, page_manager.write_responses()); + #if ENABLED(MENU_RESET_WIFI) + static millis_t wifi_record_ms = 0; + if (rts_wifi_state == PRESSED) { + rts_wifi_state = RECORDTIME; + wifi_record_ms = millis() + 7000UL; + } + else if (rts_wifi_state == RECORDTIME) { + if (wifi_record_ms && ELAPSED(millis(), wifi_record_ms)) { + OUT_WRITE(RESET_WIFI_PIN, HIGH); + rts_wifi_state = INITIAL; + SERIAL_ECHOPGM("wifi is reset"); + wifi_record_ms = 0; + } + } + #endif + // Update the LVGL interface TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER()); @@ -1316,13 +1352,13 @@ void setup() { // Identify myself as Marlin x.x.x SERIAL_ECHOLNPGM("Marlin " SHORT_BUILD_VERSION); - #ifdef STRING_DISTRIBUTION_DATE + #if defined(STRING_DISTRIBUTION_DATE) && (DISABLED(CREALITY_RTS) || defined(STRING_CONFIG_H_AUTHOR)) SERIAL_ECHO_MSG( " Last Updated: " STRING_DISTRIBUTION_DATE " | Author: " STRING_CONFIG_H_AUTHOR ); #endif - SERIAL_ECHO_MSG(" Compiled: " __DATE__); + SERIAL_ECHO_MSG(" Compiled: " __DATE__ " " __TIME__); SERIAL_ECHO_MSG(STR_FREE_MEMORY, hal.freeMemory(), STR_PLANNER_BUFFER_BYTES, sizeof(block_t) * (BLOCK_BUFFER_SIZE)); // Some HAL need precise delay adjustment @@ -1650,7 +1686,7 @@ void setup() { #if ENABLED(DWIN_CREALITY_LCD) SETUP_RUN(dwinInitScreen()); - #elif ENABLED(SOVOL_SV06_RTS) + #elif ANY(SOVOL_SV06_RTS, CREALITY_RTS) SETUP_RUN(rts.init()); #endif @@ -1758,3 +1794,13 @@ void loop() { } while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards } + +//void HardFault_Handler(void) { +// SERIAL_ECHO_MSG("HardFault_Handler"); +// OUT_WRITE(E0_AUTO_FAN_PIN, LOW); +// OUT_WRITE(FAN_PIN, LOW); +// for (int i = 0; i < 0xFFFF; i++) OUT_WRITE(FAN_PIN, HIGH); +// OUT_WRITE(E0_AUTO_FAN_PIN, HIGH); +// OUT_WRITE(FAN_PIN, HIGH); +// while(1); +//} diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 025bcb8383..96ed7b0f72 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -68,6 +68,10 @@ #include "../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #if HAS_SOUND #include "../libs/buzzer.h" #endif @@ -159,11 +163,13 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P if (wait) return thermalManager.wait_for_hotend(active_extruder); - // Allow interruption by Emergency Parser M108 - marlin.wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); - while (marlin.is_heating() && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) - marlin.idle(); - marlin.heatup_done(); + #if DISABLED(CREALITY_RTS) + // Allow interruption by Emergency Parser M108 + marlin.wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); + while (marlin.is_heating() && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) + marlin.idle(); + marlin.wait_for_heatup = false; + #endif #if ENABLED(PREVENT_COLD_EXTRUSION) // A user can cancel wait-for-heating with M108 @@ -431,6 +437,7 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh #endif TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR))); + TERN_(CREALITY_RTS, RTS_PausedPrint()); // Indicate that the printer is paused ++did_pause_print; @@ -479,9 +486,29 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh TERN_(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(leveling_was_enabled)); // restore leveling } - // If axes don't need to home then the nozzle can park - if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move - if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED); + #if ENABLED(CREALITY_RTS) + + while (planner.movesplanned() < 2 && destination != current_position) + marlin.idle(); + + queue.clear(); + delay(20); + if (!planner.has_blocks_queued()) { + if (axis_is_trusted(X_AXIS) && axis_is_trusted(Y_AXIS)) { + //if (!axes_need_homing()) + nozzle.park(0, park_point); + } + } + + #else + + // If axes don't need to home then the nozzle can park + if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move + if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED); + + #endif + + TERN_(DWIN_LCD_PROUI, if (!do_park) ui.set_status(GET_TEXT_F(MSG_PARK_FAILED))); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -489,15 +516,19 @@ bool pause_print(const float retract, const xyz_pos_t &park_point, const bool sh set_duplication_enabled(false, DXC_ext); #endif - // Unload the filament, if specified - if (unload_length) - unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); + #if DISABLED(CREALITY_RTS) + // Unload the filament, if specified + if (unload_length) + unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); + #endif TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); // Disable the Extruder for manual change disable_active_extruder(); + TERN_(CREALITY_RTS, RTS_ReheatHotend(170)); + return true; } @@ -611,6 +642,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep nozzle_timed_out = false; first_impatient_beep(max_beep_count); } + TERN_(CREALITY_RTS, marlin.wait_for_user = false); marlin.idle_no_sleep(); } TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); @@ -696,13 +728,17 @@ void resume_print( unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); if (!axes_should_home()) { - // Move XY back to saved position - destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e); - prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); + #if ENABLED(CREALITY_RTS) + destination.set(resume_position.x, resume_position.y, resume_position.z, current_position.e); + #else + // Move XY back to saved position + destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e); + prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); - // Move Z back to saved position - destination.z = resume_position.z; - prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + // Move Z back to saved position + destination.z = resume_position.z; + prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); + #endif } #if ENABLED(AUTO_BED_LEVELING_UBL) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 0dd19808bc..f0ad4425ac 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -53,6 +53,11 @@ uint32_t PrintJobRecovery::cmd_sdpos, // = 0 bool PrintJobRecovery::ui_flag_resume; // = false #endif +#if ENABLED(CREALITY_RTS) + bool PrintJobRecovery::recovery_flag; // = false + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../sd/cardreader.h" #include "../lcd/marlinui.h" #include "../gcode/queue.h" @@ -96,6 +101,20 @@ PrintJobRecovery recovery; gcode.process_subcommands_now(cmd); \ }while(0) +#if ENABLED(CREALITY_RTS) + // Feed action before pausing and resuming。rock_20220914 + #define FEEDING_DEF_DISTANCE 5 // in material: default distance of feeding material + #define FEEDING_DEF_SPEED 5 // in material: default feedrate + static void pause_resume_feedstock(uint16_t _distance, uint16_t _feedRate) { + current_position.e += _distance; + line_to_current_position(feedRate_t(_feedRate)); + current_position.e -= _distance; + gcode.process_subcommands_now(TS(F("G92.9 E"), p_float_t(current_position.e, 3))); + // Resume the feedrate + gcode.process_subcommands_now(TS(F("G1 F%s"), p_float_t(MMS_TO_MMM(feedrate_mm_s), 3))); + } +#endif + /** * Clear the recovery info */ @@ -216,6 +235,11 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW // Machine state // info.sdpos and info.current_position are pre-filled from the Stepper ISR + #if ENABLED(CREALITY_RTS) + //report_current_position(); //rock_0328 + //info.current_position = current_position; + #endif + info.feedrate = uint16_t(MMS_TO_MMM(feedrate_mm_s)); info.feedrate_percentage = feedrate_percentage; COPY(info.flow_percentage, planner.flow_percentage); @@ -270,7 +294,11 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW info.flag.dryrun = !!(marlin_debug_flags & MARLIN_DEBUG_DRYRUN); info.flag.allow_cold_extrusion = TERN0(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude); + TERN_(CREALITY_RTS, recovery_flag = PoweroffContinue); + write(); + + DEBUG_ECHO_MSG("current_position.z:", current_position.z); } } @@ -441,6 +469,8 @@ void PrintJobRecovery::resume() { const float z_raised = z_print + info.zraise; #endif + DEBUG_ECHO_MSG(">>> z_print:", z_print, ", z_raised:", z_raised, ", info.flag.raised:", info.flag.raised); + // // Home the axes that can safely be homed, and // establish the current position as best we can. @@ -486,21 +516,27 @@ void PrintJobRecovery::resume() { #if HOMING_Z_DOWN // Move to a safe XY position and home Z while avoiding the print. const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy); - PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28HZ"))); + PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28ZH" TERN_(CREALITY_RTS, "R0")))); #endif // Mark all axes as having been homed (no effect on current_position) set_all_homed(); + DEBUG_ECHO_MSG(">>> homed current_position.z:", current_position.z); + #if HAS_LEVELING // Restore Z fade and possibly re-enable bed leveling compensation. // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. // TODO: Add a G28 parameter to leave leveling disabled. - PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + (char)info.flag.leveling, 'Z', p_float_t(info.fade, 1))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + (char)info.flag.leveling, 'Z', p_float_t(info.fade, 1))); + #endif #if !HOMING_Z_DOWN // The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9. - PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3))); + #endif #endif #endif @@ -576,13 +612,37 @@ void PrintJobRecovery::resume() { PROCESS_SUBCOMMANDS_NOW(F("G12")); #endif + #if ENABLED(CREALITY_RTS) + + PROCESS_SUBCOMMANDS_NOW(F("M420 S0 Z0")); // rock_20220326 + + // Restore E position with G92.9 Rock_20220913 + // If there is a layer-changing and retracting action in GCODE, + // first extrude the material and then return to the origin + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(info.current_position.e, 3))); + + // rock_20220914 - To solve the problem of faults in the printed small model, + // the purpose is to fill the hollow section of the throat. + pause_resume_feedstock(FEEDING_DEF_DISTANCE, FEEDING_DEF_SPEED); + + #endif + // Move back over to the saved XY PROCESS_SUBCOMMANDS_NOW(TS( F("G1F3000X"), p_float_t(resume_pos.x, 3), 'Y', p_float_t(resume_pos.y, 3) )); // Move back down to the saved Z for printing - PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3))); + #if ENABLED(CREALITY_RTS) + MString<20> cmd(F("G1F600Z"), p_float_t(z_print, 3)); + PROCESS_SUBCOMMANDS_NOW(cmd); + DEBUG_ECHOLN(&cmd); + DEBUG_ECHO_MSG(">>> z_print:", z_print, "current_position.z:", current_position.z); + PROCESS_SUBCOMMANDS_NOW(F("M114")); + //safe_delay(10000); + #else + PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3))); + #endif // Restore the feedrate and percentage PROCESS_SUBCOMMANDS_NOW(TS(F("G1F"), info.feedrate)); @@ -591,8 +651,20 @@ void PrintJobRecovery::resume() { // Flowrate percentage EXTRUDER_LOOP() planner.set_flow(e, info.flow_percentage[e]); + #if ALL(CREALITY_RTS, HAS_LEVELING) + // Restore Z fade and possibly re-enable bed leveling compensation. + // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. + // TODO: Add a G28 parameter to leave leveling disabled. + PROCESS_SUBCOMMANDS_NOW(TS(F("M420S"), '0' + char(info.flag.leveling), 'Z', p_float_t(info.fade, 1))); + + // Restore Z position with G92.9 + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_print, 3))); + #endif + // Restore E position with G92.9 - PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); + #if DISABLED(CREALITY_RTS) + PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); + #endif #if ENABLED(CANCEL_OBJECTS) cancelable.state = info.cancel_state; @@ -743,6 +815,9 @@ void PrintJobRecovery::resume() { #if HAS_VOLUMETRIC_EXTRUSION DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); #endif + #if ENABLED(CREALITY_RTS) + DEBUG_ECHOLNPGM("recovery_flag: ", AS_DIGIT(recovery_flag)); + #endif } else DEBUG_ECHOLNPGM("INVALID DATA"); diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index bfa5b4717f..ae0671158c 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -166,6 +166,10 @@ class PrintJobRecovery { static bool ui_flag_resume; //!< Flag the UI to show a dialog to Resume (M1000) or Cancel (M1000C) #endif + #if ENABLED(CREALITY_RTS) + static bool recovery_flag; + #endif + static void init(); static void prepare(); diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index f0b94d0de8..16bfc1bf46 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -30,6 +30,10 @@ #include "runout.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + FilamentMonitor runout; bool FilamentMonitorBase::enabled = true, @@ -75,6 +79,7 @@ bool FilamentMonitorBase::enabled = true, #endif void event_filament_runout(const uint8_t extruder) { + if (TERN0(CREALITY_RTS, G29_flag || home_flag)) return; runout.init_for_restart(false); // Reset and disable @@ -104,6 +109,8 @@ void event_filament_runout(const uint8_t extruder) { const bool run_runout_script = !runout.host_handling; + TERN_(CREALITY_RTS, RTS_FilamentRanOut()); + #if ENABLED(HOST_ACTION_COMMANDS) const bool park_or_pause = (false diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 800d51dac6..3ba298544b 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -35,6 +35,12 @@ #include "../../../module/probe.h" #include "../../../module/temperature.h" #include "../../queue.h" +#include "../../../module/settings.h" +#include "../../../sd/cardreader.h" + +#if ENABLED(CREALITY_RTS) + #include "../../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(AUTO_BED_LEVELING_LINEAR) #include "../../../libs/least_squares_fit.h" @@ -108,6 +114,10 @@ public: bool dryrun, reenable; + #if ENABLED(CREALITY_RTS) + uint8_t showcount; + #endif + #if ANY(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR) int abl_probe_index; #endif @@ -155,6 +165,124 @@ public: constexpr grid_count_t G29_State::abl_points; #endif +#if ALL(HAS_MESH, CREALITY_RTS) + + void apply_mesh_correction(bed_mesh_t &z_values) { + float grok[3][5][5] = { 0 }; + + // lower left corner + grok[0][0][0] = -((z_values[0][4] - z_values[0][3]) + (z_values[0][3] - z_values[0][2]) + (z_values[0][2] - z_values[0][1])) / 3.0f + z_values[0][1]; + grok[1][0][0] = -((z_values[4][0] - z_values[3][0]) + (z_values[3][0] - z_values[2][0]) + (z_values[2][0] - z_values[1][0])) / 3.0f + z_values[1][0]; + grok[2][0][0] = -((z_values[4][4] - z_values[3][3]) + (z_values[3][3] - z_values[2][2]) + (z_values[2][2] - z_values[1][1])) / 3.0f + z_values[1][1]; + + grok[0][0][1] = -((z_values[0][4] - z_values[0][3]) + (z_values[0][3] - z_values[0][2])) / 2.0f + z_values[0][2]; + grok[1][0][1] = -((z_values[4][1] - z_values[3][1]) + (z_values[3][1] - z_values[2][1]) + (z_values[2][1] - z_values[1][1])) / 3.0f + z_values[1][1]; + grok[2][0][1] = -((z_values[3][4] - z_values[2][3]) + (z_values[2][3] - z_values[1][2])) / 2.0f + z_values[1][2]; + + grok[0][1][0] = -((z_values[1][4] - z_values[1][3]) + (z_values[1][3] - z_values[1][2]) + (z_values[1][2] - z_values[1][1])) / 3.0f + z_values[1][1]; + grok[1][1][0] = -((z_values[4][0] - z_values[3][0]) + (z_values[3][0] - z_values[2][0])) / 2.0f + z_values[2][0]; + grok[2][1][0] = -((z_values[4][3] - z_values[3][2]) + (z_values[3][2] - z_values[2][1])) / 2.0f + z_values[2][1]; + + grok[0][1][1] = -((z_values[1][4] - z_values[1][3]) + (z_values[1][3] - z_values[1][2])) / 2.0f + z_values[1][2]; + grok[1][1][1] = -((z_values[4][1] - z_values[3][1]) + (z_values[3][1] - z_values[2][1])) / 2.0f + z_values[2][1]; + grok[2][1][1] = -((z_values[4][4] - z_values[3][3]) + (z_values[3][3] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // upper left corner + grok[0][0][4] = -((z_values[4][4] - z_values[3][4]) + (z_values[3][4] - z_values[2][4]) + (z_values[2][4] - z_values[1][4])) / 3.0f + z_values[1][4]; + grok[1][0][4] = -((z_values[0][0] - z_values[0][1]) + (z_values[0][1] - z_values[0][2]) + (z_values[0][2] - z_values[0][3])) / 3.0f + z_values[0][3]; + grok[2][0][4] = -((z_values[4][0] - z_values[3][1]) + (z_values[3][1] - z_values[2][2]) + (z_values[2][2] - z_values[1][3])) / 3.0f + z_values[1][3]; + + grok[0][0][3] = -((z_values[4][3] - z_values[3][3]) + (z_values[3][3] - z_values[2][3]) + (z_values[2][3] - z_values[1][3])) / 3.0f + z_values[1][3]; + grok[1][0][3] = -((z_values[0][0] - z_values[0][1]) + (z_values[0][1] - z_values[0][2])) / 2.0f + z_values[0][2]; + grok[2][0][3] = -((z_values[3][0] - z_values[2][1]) + (z_values[2][1] - z_values[1][2])) / 2.0f + z_values[1][2]; + + grok[0][1][4] = -((z_values[1][0] - z_values[1][1]) + (z_values[1][1] - z_values[1][2]) + (z_values[1][2] - z_values[1][3])) / 3.0f + z_values[1][3]; + grok[1][1][4] = -((z_values[4][4] - z_values[3][4]) + (z_values[3][4] - z_values[2][4])) / 2.0f + z_values[2][4]; + grok[2][1][4] = -((z_values[4][1] - z_values[3][2]) + (z_values[3][2] - z_values[2][3])) / 2.0f + z_values[2][3]; + + grok[0][1][3] = -((z_values[4][3] - z_values[3][3]) + (z_values[3][3] - z_values[2][3])) / 2.0f + z_values[2][3]; + grok[1][1][3] = -((z_values[1][0] - z_values[1][1]) + (z_values[1][1] - z_values[1][2])) / 2.0f + z_values[1][2]; + grok[2][1][3] = -((z_values[4][0] - z_values[3][1]) + (z_values[3][1] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // upper right corner + grok[0][4][4] = -((z_values[0][4] - z_values[1][4]) + (z_values[1][4] - z_values[2][4]) + (z_values[2][4] - z_values[3][4])) / 3.0f + z_values[3][4]; + grok[1][4][4] = -((z_values[4][0] - z_values[4][1]) + (z_values[4][1] - z_values[4][2]) + (z_values[4][2] - z_values[4][3])) / 3.0f + z_values[4][3]; + grok[2][4][4] = -((z_values[0][0] - z_values[1][1]) + (z_values[1][1] - z_values[2][2]) + (z_values[2][2] - z_values[3][3])) / 3.0f + z_values[3][3]; + + grok[0][3][4] = -((z_values[3][0] - z_values[3][1]) + (z_values[3][1] - z_values[3][2]) + (z_values[3][2] - z_values[3][3])) / 3.0f + z_values[3][3]; + grok[1][3][4] = -((z_values[0][4] - z_values[1][4]) + (z_values[1][4] - z_values[2][4])) / 2.0f + z_values[2][4]; + grok[2][3][4] = -((z_values[0][1] - z_values[1][2]) + (z_values[1][2] - z_values[2][3])) / 2.0f + z_values[2][3]; + + grok[0][4][3] = -((z_values[0][3] - z_values[1][3]) + (z_values[1][3] - z_values[2][3]) + (z_values[2][3] - z_values[3][3])) / 3.0f + z_values[3][3]; + grok[1][4][3] = -((z_values[4][0] - z_values[4][1]) + (z_values[4][1] - z_values[4][2])) / 2.0f + z_values[4][2]; + grok[2][4][3] = -((z_values[1][0] - z_values[2][1]) + (z_values[2][1] - z_values[3][2])) / 2.0f + z_values[3][2]; + + grok[0][3][3] = -((z_values[0][3] - z_values[1][3]) + (z_values[1][3] - z_values[2][3])) / 2.0f + z_values[2][3]; + grok[1][3][3] = -((z_values[3][0] - z_values[3][1]) + (z_values[3][1] - z_values[3][2])) / 2.0f + z_values[3][2]; + grok[2][3][3] = -((z_values[0][0] - z_values[1][1]) + (z_values[1][1] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // lower right corner + grok[0][4][0] = -((z_values[4][4] - z_values[4][3]) + (z_values[4][3] - z_values[4][2]) + (z_values[4][2] - z_values[4][1])) / 3.0f + z_values[4][1]; + grok[1][4][0] = -((z_values[0][0] - z_values[1][0]) + (z_values[1][0] - z_values[2][0]) + (z_values[2][0] - z_values[3][0])) / 3.0f + z_values[3][0]; + grok[2][4][0] = -((z_values[0][4] - z_values[1][3]) + (z_values[1][3] - z_values[2][2]) + (z_values[2][2] - z_values[3][1])) / 3.0f + z_values[3][1]; + + grok[0][3][0] = -((z_values[3][4] - z_values[3][3]) + (z_values[3][3] - z_values[3][2]) + (z_values[3][2] - z_values[3][1])) / 3.0f + z_values[3][1]; + grok[1][3][0] = -((z_values[0][0] - z_values[1][0]) + (z_values[1][0] - z_values[2][0])) / 2.0f + z_values[2][0]; + grok[2][3][0] = -((z_values[0][3] - z_values[1][2]) + (z_values[1][2] - z_values[2][1])) / 2.0f + z_values[2][1]; + + grok[0][4][1] = -((z_values[0][1] - z_values[1][1]) + (z_values[1][1] - z_values[2][1]) + (z_values[2][1] - z_values[3][1])) / 3.0f + z_values[3][1]; + grok[1][4][1] = -((z_values[4][4] - z_values[4][3]) + (z_values[4][3] - z_values[4][2])) / 2.0f + z_values[4][2]; + grok[2][4][1] = -((z_values[1][4] - z_values[2][3]) + (z_values[2][3] - z_values[3][2])) / 2.0f + z_values[3][2]; + + grok[0][3][1] = -((z_values[3][4] - z_values[3][3]) + (z_values[3][3] - z_values[3][2])) / 2.0f + z_values[3][2]; + grok[1][3][1] = -((z_values[0][1] - z_values[1][1]) + (z_values[1][1] - z_values[2][1])) / 2.0f + z_values[2][1]; + grok[2][3][1] = -((z_values[0][4] - z_values[1][3]) + (z_values[1][3] - z_values[2][2])) / 2.0f + z_values[2][2]; + + // Calculate mean + z_values[0][0] = (grok[0][0][0] + grok[1][0][0] + grok[2][0][0]) / 3.0f; + z_values[0][1] = (grok[0][0][1] + grok[1][0][1] + grok[2][0][1] + z_values[0][1]) / 4.0f; + z_values[1][0] = (grok[0][1][0] + grok[1][1][0] + grok[2][1][0] + z_values[1][0]) / 4.0f; + z_values[1][1] = (grok[0][1][1] + grok[1][1][1] + grok[2][1][1] + z_values[1][1]) / 4.0f; + + z_values[0][4] = (grok[0][0][4] + grok[1][0][4] + grok[2][0][4] + z_values[0][4]) / 4.0f; + z_values[0][3] = (grok[0][0][3] + grok[1][0][3] + grok[2][0][3] + z_values[0][3]) / 4.0f; + z_values[1][4] = (grok[0][1][4] + grok[1][1][4] + grok[2][1][4] + z_values[1][4]) / 4.0f; + z_values[1][3] = (grok[0][1][3] + grok[1][1][3] + grok[2][1][3] + z_values[1][3]) / 4.0f; + + z_values[4][4] = (grok[0][4][4] + grok[1][4][4] + grok[2][4][4] + z_values[4][4]) / 4.0f; + z_values[3][4] = (grok[0][3][4] + grok[1][3][4] + grok[2][3][4] + z_values[3][4]) / 4.0f; + z_values[4][3] = (grok[0][4][3] + grok[1][4][3] + grok[2][4][3] + z_values[4][3]) / 4.0f; + z_values[3][3] = (grok[0][3][3] + grok[1][3][3] + grok[2][3][3] + z_values[3][3]) / 4.0f; + + z_values[4][0] = (grok[0][4][0] + grok[1][4][0] + grok[2][4][0] + z_values[4][0]) / 4.0f; + z_values[3][0] = (grok[0][3][0] + grok[1][3][0] + grok[2][3][0] + z_values[3][0]) / 4.0f; + z_values[4][1] = (grok[0][4][1] + grok[1][4][1] + grok[2][4][1] + z_values[4][1]) / 4.0f; + z_values[3][1] = (grok[0][3][1] + grok[1][3][1] + grok[2][3][1] + z_values[3][1]) / 4.0f; + + // weighted calculation method + //z_values[0][0] = (grok[0][0][0] + grok[1][0][0] + grok[2][0][0]) / 3.0f * 0.4f + z_values[0][0] * 0.6; + //z_values[0][1] = (grok[0][0][1] + grok[1][0][1] + grok[2][0][1]) / 3.0f * 0.4f + z_values[0][1] * 0.6; + //z_values[1][0] = (grok[0][1][0] + grok[1][1][0] + grok[2][1][0]) / 3.0f * 0.4f + z_values[1][0] * 0.6; + //z_values[1][1] = (grok[0][1][1] + grok[1][1][1] + grok[2][1][1]) / 3.0f * 0.4f + z_values[1][1] * 0.6; + + //z_values[0][4] = (grok[0][0][4] + grok[1][0][4] + grok[2][0][4]) / 3.0f * 0.4f + z_values[0][4] * 0.6; + //z_values[0][3] = (grok[0][0][3] + grok[1][0][3] + grok[2][0][3]) / 3.0f * 0.4f + z_values[0][3] * 0.6; + //z_values[1][4] = (grok[0][1][4] + grok[1][1][4] + grok[2][1][4]) / 3.0f * 0.4f + z_values[1][4] * 0.6; + //z_values[1][3] = (grok[0][1][3] + grok[1][1][3] + grok[2][1][3]) / 3.0f * 0.4f + z_values[1][3] * 0.6; + + //z_values[4][4] = (grok[0][4][4] + grok[1][4][4] + grok[2][4][4]) / 3.0f * 0.4f + z_values[4][4] * 0.6; + //z_values[3][4] = (grok[0][3][4] + grok[1][3][4] + grok[2][3][4]) / 3.0f * 0.4f + z_values[3][4] * 0.6; + //z_values[4][3] = (grok[0][4][3] + grok[1][4][3] + grok[2][4][3]) / 3.0f * 0.4f + z_values[4][3] * 0.6; + //z_values[3][3] = (grok[0][3][3] + grok[1][3][3] + grok[2][3][3]) / 3.0f * 0.4f + z_values[3][3] * 0.6; + + //z_values[4][0] = (grok[0][4][0] + grok[1][4][0] + grok[2][4][0]) / 3.0f * 0.4f + z_values[4][0] * 0.6; + //z_values[3][0] = (grok[0][3][0] + grok[1][3][0] + grok[2][3][0]) / 3.0f * 0.4f + z_values[3][0] * 0.6; + //z_values[4][1] = (grok[0][4][1] + grok[1][4][1] + grok[2][4][1]) / 3.0f * 0.4f + z_values[4][1] * 0.6; + //z_values[3][1] = (grok[0][3][1] + grok[1][3][1] + grok[2][3][1]) / 3.0f * 0.4f + z_values[3][1] * 0.6; + } + +#endif // HAS_MESH && CREALITY_RTS + /** * G29: Bed Leveling * @@ -233,6 +361,14 @@ G29_TYPE GcodeSuite::G29() { // Keep powered steppers from timing out reset_stepper_timeout(); + reset_bed_level(); // not 0 but NaN + + #if ENABLED(CREALITY_RTS) + G29_flag = true; + RTS_ProbingPauseHotend(); + RTS_ProbingPauseFans(); + #endif + // Q = Query leveling and G29 state const bool seenQ = ANY(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q'); @@ -621,6 +757,7 @@ G29_TYPE GcodeSuite::G29() { // Is there a next point to move to? if (abl.abl_probe_index < abl.abl_points) { + //abl.probePos.y -= probe.offset.y; _manual_goto_xy(abl.probePos); // Can be used here too! // Disable software endstops to allow manual adjustment // If G29 is not completed, they will not be re-enabled @@ -677,6 +814,7 @@ G29_TYPE GcodeSuite::G29() { // Outer loop is X with PROBE_Y_FIRST enabled // Outer loop is Y with PROBE_Y_FIRST disabled + TERN_(CREALITY_RTS, abl.showcount = 0); for (PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_SIZE && !isnan(abl.measured_z); PR_OUTER_VAR++) { int8_t inStart, inStop, inInc; @@ -793,6 +931,7 @@ G29_TYPE GcodeSuite::G29() { const float z = abl.measured_z + abl.Z_offset; abl.z_values[abl.meshCount.x][abl.meshCount.y] = z; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z)); + TERN_(CREALITY_RTS, RTS_LevelingUpdate(abl.showcount, abl.abl_points)); #if ENABLED(SOVOL_SV06_RTS) if (pt_index <= GRID_MAX_POINTS) rts.sendData(pt_index, AUTO_BED_LEVEL_ICON_VP); @@ -808,6 +947,28 @@ G29_TYPE GcodeSuite::G29() { } // inner } // outer + // Leveling data compensation interface + //for (uint8_t index = 0; index <= 3; ++index) { + // //bedlevel.z_values[3][index] *= 1.3f; + // //bedlevel.z_values[2][index] *= 1.3f; + // //bedlevel.z_values[2][index] += bedlevel.z_values[1][index] * 0.3f; + // //bedlevel.z_values[0][index] *= 1.3f; + // bedlevel.z_values[index][1] *= 0.8f; + // bedlevel.z_values[index][2] *= 0.8f; + // bedlevel.z_values[index][3] *= 0.8f; + // bedlevel.z_values[index][0] *= 0.8f; + //} + + TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.print_leveling_grid()); // print raw data + + // Force smoothing of the bottom left corner data + //float bedlevel.z_valuesTemp = 0; + //bedlevel.z_valuesTemp = (bedlevel.z_values[0][0] + bedlevel.z_values[0][1] + bedlevel.z_values[1][0]) / 3.0f; + //bedlevel.z_values[0][0] -= 0.08f; + //bedlevel.z_values[0][1] -= 0.05f; + //bedlevel.z_values[1][0] -= 0.05f; + //bedlevel.z_values[1][1] -= 0.02f; + #elif ENABLED(AUTO_BED_LEVELING_3POINT) // Probe at 3 arbitrary points @@ -837,6 +998,10 @@ G29_TYPE GcodeSuite::G29() { #endif // AUTO_BED_LEVELING_3POINT + #if ALL(HAS_MESH, CREALITY_RTS) + apply_mesh_correction(bedlevel.z_values); + #endif + ui.reset_status(); // Stow the probe. No raise for FIX_MOUNTED_PROBE. @@ -1021,9 +1186,23 @@ G29_TYPE GcodeSuite::G29() { probe.use_probing_tool(false); + #if ENABLED(Z_SAFE_HOMING) + do_blocking_move_to_xy(Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT); + //do_blocking_move_to_xy(Z_SAFE_HOMING_X_POINT-2, Z_SAFE_HOMING_Y_POINT+44.5);//rock_20220610 将Z轴复位后的终点改成平台中心 + #endif + + settings.save(); + report_current_position(); + #if ENABLED(CREALITY_RTS) + RTS_LevelingDone(); + RTS_ProbingResumeFans(); + RTS_ProbingResumeHotend(); + #endif + G29_RETURN(isnan(abl.measured_z), true); + } #endif // HAS_ABL_NOT_UBL diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 4a0ecffc4b..b8c48937fe 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -66,6 +66,10 @@ #include "../../lcd/sovol_rts/sovol_rts.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(LASER_FEATURE) #include "../../feature/spindle_laser.h" #endif @@ -254,6 +258,7 @@ void GcodeSuite::G28() { #endif TERN_(DWIN_CREALITY_LCD, dwinHomingStart()); + TERN_(CREALITY_RTS, home_flag = true); TERN_(EXTENSIBLE_UI, ExtUI::onHomingStart()); planner.synchronize(); // Wait for planner moves to finish! @@ -578,6 +583,15 @@ void GcodeSuite::G28() { TERN_(DWIN_CREALITY_LCD, dwinHomingDone()); TERN_(EXTENSIBLE_UI, ExtUI::onHomingDone()); + #if ENABLED(CREALITY_RTS) + home_flag = false; + RTS_MoveAxisHoming(); + //DEBUG_ECHOLNPGM(" leveling_flag=: ", leveling_flag); + // If it is in leveling, the automatic compensation function will not be restored + //process_subcommands_now_P(leveling_flag ? PSTR("M420 S0") : PSTR("M420 S1 Z10")); + st_bedNozzleHeightCal.goHomeSta = GO_HOME_DONE; + #endif + report_current_position(); TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(old_grblstate)); diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp index 0d1e204800..67d2a5e91d 100644 --- a/Marlin/src/gcode/config/M220.cpp +++ b/Marlin/src/gcode/config/M220.cpp @@ -22,6 +22,9 @@ #include "../gcode.h" #include "../../module/motion.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif /** * M220: Set Feedrate Percentage @@ -46,4 +49,5 @@ void GcodeSuite::M220() { if (parser.seen_test('B')) backup_feedrate_percentage = now_feedrate_perc; if (parser.seenval('S')) feedrate_percentage = parser.value_int(); + TERN_(CREALITY_RTS, RTS_UpdateFeedrate(feedrate_percentage)); } diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index a7653a4037..e8b38cf3b0 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -42,6 +42,10 @@ #include "../../MarlinCore.h" #endif +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../feature/powerloss.h" +#endif + #if ENABLED(PSU_CONTROL) /** @@ -127,4 +131,6 @@ void GcodeSuite::M81() { #elif HAS_SUICIDE marlin.suicide(); #endif + + //OUT_WRITE(SHUTDOWN_PIN, LOW); delay(2000); } diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 8b35400c52..4d620155bc 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -1301,7 +1301,7 @@ void GcodeSuite::process_subcommands_now(char * gcode) { TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_position_moving()); break; case PAUSED_FOR_USER: - SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER); + if (TERN1(CREALITY_RTS, change_page_font == 7)) SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER); TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD)); break; case PAUSED_FOR_INPUT: diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 19d0ae9b63..c5250798c4 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -39,6 +39,10 @@ #include "../../libs/hex_print.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + //#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities #if ENABLED(EXTENDED_CAPABILITIES_REPORT) @@ -46,11 +50,14 @@ #if ENABLED(MINIMAL_CAP_LINES) if (ena) SERIAL_ECHOLNPGM("Cap:", name, ":1"); #else - SERIAL_ECHOPGM("Cap:", name); - SERIAL_CHAR(':', '0' + ena); - SERIAL_EOL(); + SERIAL_ECHOLN(F("Cap:"), name, C(':'), C('0' + ena)); #endif } + #if ENABLED(CREALITY_RTS) + inline void cap_line_uchar(FSTR_P const name, const uint8_t ena) { + SERIAL_ECHOLN(F("Cap:"), name, C(':'), C('0' + ena)); + } + #endif #endif /** @@ -135,6 +142,11 @@ void GcodeSuite::M115() { // BINARY_FILE_TRANSFER (M28 B1) cap_line(F("BINARY_FILE_TRANSFER"), ENABLED(BINARY_FILE_TRANSFER)); // TODO: Use SERIAL_IMPL.has_feature(port, SerialFeature::BinaryFileTransfer) once implemented + #if ENABLED(CREALITY_RTS) + // Creality New Cloud Print Information + cap_line_uchar(F("IS_PLR"), g_cloudPLRStatusValue); // Send status to continue print after power failure + #endif + // EEPROM (M500, M501) cap_line(F("EEPROM"), ENABLED(EEPROM_SETTINGS)); @@ -247,6 +259,9 @@ void GcodeSuite::M115() { // CONFIG_EXPORT cap_line(F("CONFIG_EXPORT"), ENABLED(CONFIGURATION_EMBEDDING)); + // Creality WiFi + TERN_(CREALITY_RTS, cap_line(F("WIFI"), wifi_enable_flag)); + // Machine Geometry #if ENABLED(M115_GEOMETRY_REPORT) constexpr xyz_pos_t bmin{0}, diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp index 81c16ebdfe..63d0e345ea 100644 --- a/Marlin/src/gcode/lcd/M0_M1.cpp +++ b/Marlin/src/gcode/lcd/M0_M1.cpp @@ -36,6 +36,9 @@ #include "../../lcd/extui/ui_api.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(HOST_PROMPT_SUPPORT) #include "../../feature/host_actions.h" #endif @@ -45,6 +48,9 @@ * M1: Conditional stop - Wait for user button press on LCD */ void GcodeSuite::M0_M1() { + + TERN_(CREALITY_RTS, RTS_CommandPause()); + millis_t ms = 0; if (parser.seenval('P')) ms = parser.value_millis(); // Milliseconds to wait if (parser.seenval('S')) ms = parser.value_millis_from_seconds(); // Seconds to wait diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp index b489b659ae..36305653c8 100644 --- a/Marlin/src/gcode/motion/G0_G1.cpp +++ b/Marlin/src/gcode/motion/G0_G1.cpp @@ -22,6 +22,9 @@ #include "../gcode.h" #include "../../module/motion.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #include "../../MarlinCore.h" @@ -122,5 +125,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) { TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving()); #endif - TERN_(SOVOL_SV06_RTS, RTS_PauseMoveAxisPage()); + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) + RTS_PauseMoveAxisPage(); + #endif } diff --git a/Marlin/src/gcode/ota/M936.cpp b/Marlin/src/gcode/ota/M936.cpp index 353e423c77..0b94ceb597 100644 --- a/Marlin/src/gcode/ota/M936.cpp +++ b/Marlin/src/gcode/ota/M936.cpp @@ -26,6 +26,10 @@ #include "../gcode.h" #include "../../libs/BL24CXX.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #define OTA_FLAG_EEPROM 90 //#define DEBUG_OUT 1 @@ -43,11 +47,21 @@ void GcodeSuite::M936() { // Set the OTA board firmware upgrade flag ahead of reboot. ota_update_flag = 0x01; DEBUG_ECHOLNPGM("Motherboard upgrade flag set"); + TERN_(CREALITY_RTS, RTS_Error(Error_205)); break; + + #if ENABLED(CREALITY_RTS) + case 3: + // Set the OTA screen firmware upgrade flag ahead of reboot. + ota_update_flag = 0x02; + DEBUG_ECHOLNPGM("DWIN upgrade flag set"); + TERN_(CREALITY_RTS, RTS_Error(Error_206)); + break; + #endif } switch (ota) { - case 2: + case 2: TERN_(CREALITY_RTS, case 3:) BL24CXX::write(OTA_FLAG_EEPROM, &ota_update_flag, sizeof(ota_update_flag)); safe_delay(100); hal.reboot(); diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 0014ca44a5..34b6e2b447 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -37,6 +37,10 @@ GCodeQueue queue; #include "../MarlinCore.h" #include "../core/bug_on.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(BINARY_FILE_TRANSFER) #include "../feature/binary_stream.h" #endif @@ -112,7 +116,10 @@ void GCodeQueue::RingBuffer::commit_command(const bool skip_ok bool GCodeQueue::RingBuffer::enqueue(const char *cmd, const bool skip_ok/*=true*/ OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind/*=-1*/) ) { - if (*cmd == ';' || length >= BUFSIZE) return false; + // SERIAL_ECHOLNPGM(" length=: ",length); + // SERIAL_ECHOLNPGM(" index_r=: ", index_r); + // SERIAL_ECHOLNPGM(" index_w=: ", index_w); + if (*cmd == ';' || length >= BUFSIZE) return false; //这里的会导致主板一直选项idle(); strcpy(commands[index_w].buffer, cmd); commit_command(skip_ok OPTARG(HAS_MULTI_SERIAL, serial_ind)); return true; @@ -191,7 +198,13 @@ bool GCodeQueue::process_injected_command() { * Enqueue and return only when commands are actually enqueued. * Never call this from a G-code handler! */ -void GCodeQueue::enqueue_one_now(const char * const cmd) { while (!enqueue_one(cmd)) marlin.idle(); } +void GCodeQueue::enqueue_one_now(const char * const cmd) { + uint16_t count = 0; + while (!enqueue_one(cmd)) { + marlin.idle(); + if (count++ > 500) { SERIAL_ECHO_MSG("_full"); break; } + } +} void GCodeQueue::enqueue_one_now(FSTR_P const fcmd) { while (!enqueue_one(fcmd)) marlin.idle(); } /** @@ -216,6 +229,7 @@ bool GCodeQueue::enqueue_one(FSTR_P const fcmd) { void GCodeQueue::enqueue_now_P(PGM_P const pgcode) { size_t i = 0; PGM_P p = pgcode; + if (TERN0(CREALITY_RTS, ring_buffer.full())) return; // rock——20220815 for (;;) { char c; while ((c = pgm_read_byte(&p[i])) && c != '\n') i++; @@ -564,18 +578,40 @@ void GCodeQueue::get_serial_commands() { * always receives complete command-lines, they can go directly * into the main command queue. */ + uint16_t SD_ReadTimeout = 0; + bool SD_Card_status = true; + bool sd_printing_autopause = false; inline void GCodeQueue::get_sdcard_commands() { static uint8_t sd_input_state = PS_NORMAL; - // Get commands if there are more in the file - if (!card.isStillFetching()) return; + if (!card.isStillFetching() || !card.isSDCardInserted()) return; int sd_count = 0; - while (!ring_buffer.full() && !card.eof()) { + bool card_eof = card.eof(); + while (!ring_buffer.full() && !card.eof() && card.isSDCardInserted()) { const int16_t n = card.get(); - const bool card_eof = card.eof(); - if (n < 0 && !card_eof) { SERIAL_ERROR_MSG(STR_SD_ERR_READ); continue; } - + card_eof = card.eof(); + if (n < 0 && !card_eof) { + SERIAL_ERROR_MSG(STR_SD_ERR_READ); continue; + } + // if (n < 0 && !card_eof) { + // if (SD_ReadTimeout > 50) { + // if (SD_Card_status) { + // SERIAL_ERROR_MSG(STR_SD_ERR_READ); + // // SD Read Error Auto print pause; + // if (!sd_printing_autopause) { + // sd_printing_autopause = true; + // queue.inject_P(PSTR("M25")); + // } + // } + // SD_Card_status = false; + // SD_ReadTimeout = 0; + // break; + // } + // SD_ReadTimeout++; + // } + // else + // SD_ReadTimeout = 0; CommandLine &command = ring_buffer.commands[ring_buffer.index_w]; const char sd_char = (char)n; const bool is_eol = ISEOL(sd_char); @@ -602,10 +638,15 @@ void GCodeQueue::get_serial_commands() { TERN_(POWER_LOSS_RECOVERY, recovery.cmd_sdpos = card.getIndex()); } - if (card.eof()) card.fileHasFinished(); // Handle end of file reached + if (card.eof()) { + // Handle end of file reached + card.fileHasFinished(); + TERN_(CREALITY_RTS, RTS_FileHasFinished()); + } } - else + else { process_stream_char(sd_char, sd_input_state, command.buffer, sd_count); + } } } @@ -637,8 +678,7 @@ void GCodeQueue::exhaust() { * Get the next command in the queue, optionally log it to SD, then dispatch it */ void GCodeQueue::advance() { - - // Process immediate commands + // Process immediate commands //有立即执行的指令 if (process_injected_command_P() || process_injected_command()) return; // Return if the G-code buffer is empty diff --git a/Marlin/src/gcode/sd/M23.cpp b/Marlin/src/gcode/sd/M23.cpp index 5a7d450e09..1a551369eb 100644 --- a/Marlin/src/gcode/sd/M23.cpp +++ b/Marlin/src/gcode/sd/M23.cpp @@ -27,6 +27,9 @@ #include "../gcode.h" #include "../../sd/cardreader.h" #include "../../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif /** * M23: Select File @@ -44,6 +47,7 @@ void GcodeSuite::M23() { card.openFileRead(parser.string_arg); TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0)); + TERN_(CREALITY_RTS, RTS_OpenFileCloud()); } #endif // HAS_MEDIA diff --git a/Marlin/src/gcode/sd/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp index 6eb1375db4..6647f5e110 100644 --- a/Marlin/src/gcode/sd/M24_M25.cpp +++ b/Marlin/src/gcode/sd/M24_M25.cpp @@ -28,6 +28,9 @@ #include "../../sd/cardreader.h" #include "../../module/printcounter.h" #include "../../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif #if ENABLED(PARK_HEAD_ON_PAUSE) #include "../../feature/pause.h" @@ -86,6 +89,8 @@ void GcodeSuite::M24() { #endif ui.reset_status(); + + TERN_(CREALITY_RTS, RTS_PrintStartedSD()); } /** diff --git a/Marlin/src/gcode/temp/M104_M109.cpp b/Marlin/src/gcode/temp/M104_M109.cpp index d27ff75d39..45474fffda 100644 --- a/Marlin/src/gcode/temp/M104_M109.cpp +++ b/Marlin/src/gcode/temp/M104_M109.cpp @@ -38,6 +38,10 @@ #include "../../MarlinCore.h" // for startOrResumeJob, etc. +#if ENABLED(CREALITY_RTS) + #include "../../lcd/rts/lcd_rts.h" +#endif + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) #include "../../module/printcounter.h" #if ENABLED(CANCEL_OBJECTS) @@ -110,6 +114,8 @@ void GcodeSuite::M104_M109(const bool isM109) { #endif thermalManager.setTargetHotend(temp, target_extruder); + TERN_(CREALITY_RTS, temphot = temp); + #if ENABLED(DUAL_X_CARRIAGE) if (idex_is_duplicating() && target_extruder == 0) thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index d1d4bfd0a6..cd4972fd68 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -96,11 +96,17 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; #endif #if HAS_MULTI_LANGUAGE + + #if ENABLED(CREALITY_RTS) + #include "rts/lcd_rts.h" + #endif + uint8_t MarlinUI::language; // Initialized by settings.load void MarlinUI::set_language(const uint8_t lang) { if (lang < NUM_LANGUAGES) { language = lang; TERN_(HAS_MARLINUI_U8GLIB, update_language_font()); + TERN_(CREALITY_RTS, rts.updateLanguageDisplay()); return_to_status(); refresh(); } diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 8ec25ab5c6..e4e9c0b098 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -223,6 +223,8 @@ public: #if HAS_MULTI_LANGUAGE static uint8_t language; static void set_language(const uint8_t lang); + #else + static constexpr uint8_t language = 0; #endif #if HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/sovol_rts/sovol_rts.cpp b/Marlin/src/lcd/sovol_rts/sovol_rts.cpp index 82a80bdd4a..0c5633b6f3 100644 --- a/Marlin/src/lcd/sovol_rts/sovol_rts.cpp +++ b/Marlin/src/lcd/sovol_rts/sovol_rts.cpp @@ -110,7 +110,6 @@ float axis_unit = 10; int16_t update_time_value = 0; bool poweroff_continue = false; -char commandbuf[30]; static SovolPage change_page_number = ID_Startup; diff --git a/Marlin/src/lcd/sovol_rts/sovol_rts.h b/Marlin/src/lcd/sovol_rts/sovol_rts.h index 15642e06c9..daeef239b0 100644 --- a/Marlin/src/lcd/sovol_rts/sovol_rts.h +++ b/Marlin/src/lcd/sovol_rts/sovol_rts.h @@ -381,8 +381,6 @@ extern void RTS_Init(); extern int16_t update_time_value; extern bool poweroff_continue; -extern bool sdcard_pause_check; -extern bool sd_printing_autopause; extern bool pause_flag; void RTS_AutoBedLevelPage(); diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 5b7be5d00c..46fdaeca2c 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -33,6 +33,8 @@ #if ENABLED(SOVOL_SV06_RTS) #include "../lcd/sovol_rts/sovol_rts.h" +#elif ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(FT_MOTION) @@ -235,6 +237,7 @@ void Endstops::enable(const bool onoff) { hit_on_purpose(); else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHome_L, ID_KillHome_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_202)); marlin.kill(GET_TEXT_F(MSG_KILL_HOMING_FAILED)); } } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 1012cc4150..e323d4332c 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -35,7 +35,10 @@ #if IS_SCARA #include "../libs/buzzer.h" - #include "../lcd/marlinui.h" +#endif + +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(POLAR) @@ -2220,6 +2223,14 @@ void prepare_line_to_destination() { DEBUG_ECHOLNPGM(")"); } + #if ENABLED(PROBE_ACTIVATION_SWITCH) + if (axis == Z_AXIS && HIGH == READ(PROBE_ACTIVATION_SWITCH_PIN)) { + WRITE(PROBE_TARE_PIN, LOW); + delay(200); + WRITE(PROBE_TARE_PIN, HIGH); + } + #endif + // Only do some things when moving towards an endstop const int8_t axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) ? TOOL_X_HOME_DIR(active_extruder) : home_dir(axis); @@ -2279,13 +2290,12 @@ void prepare_line_to_destination() { planner.synchronize(); if (is_home_dir) { + endstops.validate_homing_move(); #if HOMING_Z_WITH_PROBE && HAS_QUIET_PROBING if (axis == Z_AXIS && final_approach) probe.set_devices_paused_for_probing(false); #endif - endstops.validate_homing_move(); - // Re-enable stealthChop if used. Disable diag1 pin on driver. #if ENABLED(SENSORLESS_HOMING) end_sensorless_homing_per_axis(axis, stealth_states); @@ -2459,6 +2469,7 @@ void prepare_line_to_destination() { #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_STATE) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) #define _ANDCANT(N) && !_CAN_HOME(N) if (true MAIN_AXIS_MAP(_ANDCANT)) return; + #undef _CAN_HOME #endif if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> homeaxis(", C(AXIS_CHAR(axis)), ")"); @@ -2757,6 +2768,8 @@ void prepare_line_to_destination() { destination[axis] = current_position[axis]; + //if (axis == Z_AXIS) current_position.z -= probe.offset.z; //rock_20220801 手动对高功能。 + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); #endif @@ -2847,7 +2860,32 @@ void set_axis_is_at_home(const AxisEnum axis) { /** * Z Probe Z Homing? Account for the probe's Z offset. */ - #if HAS_BED_PROBE && Z_HOME_TO_MIN + #if 0 + #if HAS_BED_PROBE && Z_HOME_TO_MAX // Z_HOME_TO_MIN Rock_20220827 + if (axis == Z_AXIS) { + #if HOMING_Z_WITH_PROBE + + SERIAL_ECHOLNPGM(" current_position.z_old=: ", current_position.z); + current_position.z -= probe.offset.z; + SERIAL_ECHOLNPGM(" probe.offset.z=: ", probe.offset.z); + SERIAL_ECHOLNPGM(" current_position.z_new=: ", current_position.z); + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***\n> probe.offset.z = ", probe.offset.z); + + #else + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z HOMED TO ENDSTOP ***"); + + #endif + } + #endif + + #if ENABLED(BLTOUCH_AND_Z_LIMIT) // 正方向回原点进行Z轴补偿 + if (axis == Z_AXIS) current_position.z -= probe.offset.z; + #endif + #endif + + #if HAS_BED_PROBE && Z_HOME_DIR < 0 if (axis == Z_AXIS) { #if HOMING_Z_WITH_PROBE #if ENABLED(BD_SENSOR) @@ -2861,6 +2899,15 @@ void set_axis_is_at_home(const AxisEnum axis) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z homed to ENDSTOP ***"); #endif } + #elif HAS_BED_PROBE && Z_HOME_DIR > 0 // Return to the origin in the positive direction for Z-axis compensation + if (axis == Z_AXIS) { + #if ALL(CREALITY_RTS, BLTOUCH, HOMING_Z_WITH_PROBE) && Z_HOME_DIR > 0 + if (st_bedNozzleHeightCal.bedNozzleHeightCalFinishFlag) + current_position.z -= probe.offset.z + st_bedNozzleHeightCal.zCoordinateOffset; + #else + //current_position.z -= probe.offset.z; + #endif + } #endif TERN_(I2C_POSITION_ENCODERS, I2CPEM.homed(axis)); @@ -2886,3 +2933,555 @@ void set_axis_is_at_home(const AxisEnum axis) { home_offset[axis] = v; } #endif + +#if ENABLED(CREALITY_RTS) + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + + float homeaxis_bl(const AxisEnum axis, const feedRate_t fr_mm_fast, const feedRate_t fr_mm_slow) { + float coordinateOffset = VALUE_INVALID_8BIT; + + #if ANY(MORGAN_SCARA, MP_SCARA) + // Only Z homing (with probe) is permitted + if (axis != Z_AXIS) { BUZZ(100, 880); return; } + #else + #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_ENDSTOP) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) + if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return 0xFFFF; + #undef _CAN_HOME + #endif + + if (ENABLED(USER_LEVEL_DEBUG)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl start current_position.z * 100 = ", current_position.z * 100); + DEBUG_ECHOLNPGM(">>> homeaxis(", axis_codes[axis], ")"); + } + + // const int axis_home_dir = -TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + // ? x_home_dir(active_extruder) : home_dir(axis); + //由于此时使用了最大限位开关,Z_HOME_DIR被设置成1,不能用上面的判断,所以此处强制赋值为-1 + const int axis_home_dir = -1; + + // Homing Z towards the bed? Deploy the Z probe or endstop. + if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.deploy())) // 弹出bltouch + return VALUE_INVALID_8BIT; + + // Set flags for X, Y, Z motor locking + #if HAS_EXTRA_ENDSTOPS + switch (axis) { + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); + default: break; + } + #endif + + // Fast move towards endstop until triggered + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Home 1 Fast:"); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS && bltouch.deploy()) return VALUE_INVALID_8BIT; // The initial DEPLOY + #endif + + #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) + const xy_float_t backoff = SENSORLESS_BACKOFF_MM; + if (((ENABLED(X_SENSORLESS) && axis == X_AXIS) || (ENABLED(Y_SENSORLESS) && axis == Y_AXIS)) && backoff[axis]) + do_homing_move(axis, -ABS(backoff[axis]) * axis_home_dir, homing_feedrate(axis)); + #endif + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl start to move z * 100 = ", axis * 100, + "\nhomeaxis_bl current scalin * 100 = ", (int)(max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir * 100), + ); + + abce_pos_t target1 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target1[axis] * 100 = ", target1[axis] * 100); + + do_homing_move(axis, 0.90f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(fr_mm_fast)); + // do_homing_move(axis, 1.5f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir);//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target2 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target2[axis] * 100 = ", target2[axis] * 100); + + // 获取z轴两坐标系的差值 + #if ANY(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(target2[axis] + target1[axis]); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(target2[axis] + target1[axis]); + #endif + coordinateOffset = target2[axis] + target1[axis]; + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-1 Fast: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-1 Fast: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + abce_pos_t target3 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target3[axis] * 100 = ", target3[axis] * 100); + + //do_homing_move(axis, 0.75f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST * 15)); + do_homing_move(axis, 0.25f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir, MMM_TO_MMS(fr_mm_slow));//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target4 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target4[axis] * 100 = ", target4[axis] * 100); + + // 获取z轴两坐标系的差值 + #if ENABLED(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(rts.GetzCoordinateOffset() + /*target3[axis] + */target4[axis]); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(gLcdSermoonV2UI.GetzCoordinateOffset() + /*target3[axis] + */target4[axis]); + #endif + coordinateOffset += target4[axis]; + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-2 Fast: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100, " coordinateOffset * 100 = ", coordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 1-2 Fast: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,此时的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z] * 100 = ", current_position[axis] * 100); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) + #endif + + // When homing Z with probe respect probe clearance + const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS)); + const float bump = axis_home_dir * ( + use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis) + ); + + // If a second homing move is configured... + if (bump) { + // Move away from the endstop by the axis HOMING_BUMP_MM + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Move Away:"); + do_homing_move(axis, -bump + #if HOMING_Z_WITH_PROBE + , MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_FEEDRATE_FAST : 0) + #endif + ); + + #if ENABLED(DETECT_BROKEN_ENDSTOP) + // Check for a broken endstop + EndstopEnum es; + switch (axis) { + default: + case X_AXIS: es = X_ENDSTOP; break; + case Y_AXIS: es = Y_ENDSTOP; break; + case Z_AXIS: es = Z_ENDSTOP; break; + } + if (TEST(endstops.state(), es)) { + SERIAL_ECHO_MSG("Bad ", axis_codes[axis], " Endstop?"); + kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); + } + #endif + + // Slow move towards endstop until triggered + if (ENABLED(USER_LEVEL_DEBUG)) DEBUG_ECHOLNPGM("Home 2 Slow:"); //第二次测量 + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE) + #endif + + abce_pos_t target5 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target5[axis] * 100 = ", target5[axis] * 100); + + do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); + + abce_pos_t target6 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target6[axis] * 100 = ", target6[axis] * 100); + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,此时的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + if (ENABLED(USER_LEVEL_DEBUG)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z_2 * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z]_2 * 100 = ", current_position[axis] * 100); + + // 第二次测量值 + #if ENABLED(DWIN_CREALITY_CR200B_PRO) + rts.setZCoordinateOffset(rts.GetzCoordinateOffset() - (target5[axis] + target6[axis])); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + gLcdSermoonV2UI.setZCoordinateOffset(gLcdSermoonV2UI.GetzCoordinateOffset() - (target5[axis] + target6[axis])); + #endif + coordinateOffset -= (target5[axis] + target6[axis]); + + if (ENABLED(USER_LEVEL_DEBUG)) { + #if ANY(DWIN_CREALITY_SERMOON_D3, DWIN_CREALITY_CR200B_PRO) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 2 Slow: zCoordinateOffset * 100 = ", rts.zCoordinateOffset * 100, + "\nhomeaxis_bl Home 2 Slow: coordinateOffset * 100 = ", coordinateOffset * 100); + #elif ENABLED(DWIN_CREALITY_SERMOON_V2) + SERIAL_ECHOLNPGM("\nhomeaxis_bl Home 2 Slow: zCoordinateOffset * 100 = ", gLcdSermoonV2UI.zCoordinateOffset * 100); + #endif + SERIAL_EOL(); + } + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS) bltouch.stow(); // The final STOW + #endif + } + + #if HAS_EXTRA_ENDSTOPS + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const float adj = ABS(endstops.x2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_x_lock(false); + stepper.set_x2_lock(false); + } + } + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const float adj = ABS(endstops.y2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_y_lock(false); + stepper.set_y2_lock(false); + } + } + #endif + + // Reset flags for X, Y, Z motor locking + switch (axis) { + default: break; + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(false); + } + #endif + + #ifdef TMC_HOME_PHASE + // move back to homing phase if configured and capable + backout_to_tmc_homing_phase(axis); + #endif + + #if IS_SCARA + + set_axis_is_at_home(axis); + sync_plan_position(); + + #elif ENABLED(DELTA) + + // Delta has already moved all three towers up in G28 + // so here it re-homes each tower in turn. + // Delta homing treats the axes as normal linear axes. + + const float adjDistance = delta_endstop_adj[axis], + minDistance = (MIN_STEPS_PER_SEGMENT) * planner.mm_per_step[axis]; + + // Retrace by the amount specified in delta_endstop_adj if more than min steps. + if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("adjDistance:", adjDistance); + do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); + } + + #else // CARTESIAN / CORE / MARKFORGED_XY + + //set_axis_is_at_home(axis); + sync_plan_position(); + + destination[axis] = current_position[axis]; + + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + + #endif + + // Put away the Z probe + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && probe.stow()) return VALUE_INVALID_8BIT; + #endif + + #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) + const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; + if (endstop_backoff[axis]) { + current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; + line_to_current_position( + #if HOMING_Z_WITH_PROBE + (axis == Z_AXIS) ? MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST) : + #endif + homing_feedrate(axis) + ); + + #if ENABLED(SENSORLESS_HOMING) + planner.synchronize(); + if (false + #if ANY(IS_CORE, MARKFORGED_XY) + || axis != NORMAL_AXIS + #endif + ) safe_delay(200); // Short delay to allow belts to spring back + #endif + } + #endif + + // Clear retracted status if homing the Z axis + TERN_(FWRETRACT, if (axis == Z_AXIS) fwretract.current_hop = 0.0); + + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl end current_position.z * 100 = ", current_position.z * 100); + SERIAL_EOL(); + } + return coordinateOffset; + } + + #else // !BLTOUCH_AND_Z_LIMIT + + void homeaxis_bl(const AxisEnum axis) { + + #if IS_SCARA + // Only Z homing (with probe) is permitted + if (axis != Z_AXIS) { BUZZ(100, 880); return; } + #else + #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_ENDSTOP) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) + if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return; + #endif + + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOLNPGM("\nhomeaxis_bl start current_position.z * 100 = ", current_position.z * 100); + DEBUG_ECHOLNPGM(">>> homeaxis(", axis_codes[axis], ")"); + } + + // const int axis_home_dir = -TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) + // ? x_home_dir(active_extruder) : home_dir(axis); + //由于此时使用了最大限位开关,Z_HOME_DIR被设置成1,不能用上面的判断,所以此处强制赋值为-1 + const int axis_home_dir = -1; + + // Homing Z towards the bed? Deploy the Z probe or endstop. + if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.deploy())) // 弹出bltouch + return; + + // Set flags for X, Y, Z motor locking + #if HAS_EXTRA_ENDSTOPS + switch (axis) { + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); + default: break; + } + #endif + + // Fast move towards endstop until triggered + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 1 Fast:"); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS && bltouch.deploy()) return; // The initial DEPLOY + #endif + + #if DISABLED(DELTA) && defined(SENSORLESS_BACKOFF_MM) + const xy_float_t backoff = SENSORLESS_BACKOFF_MM; + if (((ENABLED(X_SENSORLESS) && axis == X_AXIS) || (ENABLED(Y_SENSORLESS) && axis == Y_AXIS)) && backoff[axis]) + do_homing_move(axis, -ABS(backoff[axis]) * axis_home_dir, homing_feedrate(axis)); + #endif + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl start to move z * 100 = ", axis * 100, + "\nhomeaxis_bl current scalin * 100 = ", (int)(max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir * 100), + ); + } + + abce_pos_t target1 = planner.get_axis_positions_mm(); // 获取向下移动前的坐标 + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target1[axis] * 100 = ", target1[axis] * 100); + + do_homing_move(axis, 1.5f * max_length(TERN(DELTA, Z_AXIS, axis)) * axis_home_dir);//Z轴向下移动,移动距离为当前 Z_MAX_POS x 1.5f,当bltouch有反馈信号时,停止运行 + abce_pos_t target2 = planner.get_axis_positions_mm(); // 获取向下移动后的坐标 + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPGM("\nhomeaxis_bl target2[axis] * 100 = ", target2[axis] * 100); + + #if ENABLED(CREALITY_RTS) + // 获取z轴两坐标系的差值 + // 这里的“+probe.offset.z”,是因为执行了G28后,Z轴会走一段路程,其长度为probe.offset.z ,这也是实现下限位必须走的距离 + // gLcdSermoonV2UI.setZCoordinateOffset(target2[axis] + target1[axis] + gLcdSermoonV2UI.GetzCoordinateOffset() + probe.offset.z); + // st_bedNozzleHeightCal.zCoordinateOffset=target2[axis] + target1[axis] + st_bedNozzleHeightCal.zCoordinateOffset+probe.offset.z; + st_bedNozzleHeightCal.zCoordinateOffset=target2[axis] + target1[axis]; + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl zCoordinateOffset * 100 = ", st_bedNozzleHeightCal.zCoordinateOffset * 100); + SERIAL_EOL(); + } + + // 当前z位置: + // 这时候是bltouch刚刚碰到热床,测试的坐标其实就是 0 - probe.offset.z。 + current_position[axis] = 0 - probe.offset.z; + + #endif + + #if HOMING_Z_WITH_PROBE + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl probe.offset.z * 100 = ", probe.offset.z * 100, + "\nhomeaxis_bl current_position[Z] * 100 = ", current_position[axis] * 100); + } + #endif + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) + #endif + + // When homing Z with probe respect probe clearance + const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(Z_AXIS)); + const float bump = axis_home_dir * ( + use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(Z_AXIS)) : home_bump_mm(axis) + ); + + // If a second homing move is configured... + if (bump) { + // Move away from the endstop by the axis HOMING_BUMP_MM + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:"); + do_homing_move(axis, -bump + OPTARG(HOMING_Z_WITH_PROBE, MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_FEEDRATE_FAST : 0)) + ); + + #if ENABLED(DETECT_BROKEN_ENDSTOP) + // Check for a broken endstop + EndstopEnum es; + switch (axis) { + default: + case X_AXIS: es = X_ENDSTOP; break; + case Y_AXIS: es = Y_ENDSTOP; break; + case Z_AXIS: es = Z_ENDSTOP; break; + } + if (TEST(endstops.state(), es)) { + SERIAL_ECHO_MSG("Bad ", axis_codes[axis], " Endstop?"); + kill(GET_TEXT(MSG_KILL_HOMING_FAILED)); + } + #endif + + // Slow move towards endstop until triggered + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 2 Slow:"); //第二次测量 + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) && DISABLED(BLTOUCH_HS_MODE) + if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE) + #endif + + do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); + + #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) + if (axis == Z_AXIS) bltouch.stow(); // The final STOW + #endif + } + + #if HAS_EXTRA_ENDSTOPS + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const float adj = ABS(endstops.x2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_x_lock(false); + stepper.set_x2_lock(false); + } + } + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const float adj = ABS(endstops.y2_endstop_adj); + if (adj) { + if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + stepper.set_y_lock(false); + stepper.set_y2_lock(false); + } + } + #endif + + // Reset flags for X, Y, Z motor locking + switch (axis) { + default: break; + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(false); + } + #endif + + #ifdef TMC_HOME_PHASE + // move back to homing phase if configured and capable + backout_to_tmc_homing_phase(axis); + #endif + + #if IS_SCARA + + set_axis_is_at_home(axis); + sync_plan_position(); + + #elif ENABLED(DELTA) + + // Delta has already moved all three towers up in G28 + // so here it re-homes each tower in turn. + // Delta homing treats the axes as normal linear axes. + + const float adjDistance = delta_endstop_adj[axis], + minDistance = (MIN_STEPS_PER_SEGMENT) * planner.mm_per_step[axis]; + + // Retrace by the amount specified in delta_endstop_adj if more than min steps. + if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("adjDistance:", adjDistance); + do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); + } + + #else // CARTESIAN / CORE / MARKFORGED_XY + + //set_axis_is_at_home(axis); + sync_plan_position(); + + destination[axis] = current_position[axis]; + + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + + #endif + + // Put away the Z probe + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && probe.stow()) return; + #endif + + #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) + const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; + if (endstop_backoff[axis]) { + current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; + line_to_current_position(TERN_(HOMING_Z_WITH_PROBE, axis == Z_AXIS ? MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST) :) homing_feedrate(axis)); + + #if ENABLED(SENSORLESS_HOMING) + planner.synchronize(); + if (false + #if ANY(IS_CORE, MARKFORGED_XY) + || axis != NORMAL_AXIS + #endif + ) safe_delay(200); // Short delay to allow belts to spring back + #endif + } + #endif + + // Clear retracted status if homing the Z axis + #if ENABLED(FWRETRACT) + if (axis == Z_AXIS) fwretract.current_hop = 0.0; + #endif + + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("\nhomeaxis_bl end current_position.z * 100 = ", current_position.z * 100); + SERIAL_EOL(); + } + } + + #endif // !BLTOUCH_AND_Z_LIMIT +#endif // CREALITY_RTS diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 8050e66448..819def342e 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -74,6 +74,10 @@ extern xyz_pos_t cartes; constexpr feedRate_t z_probe_fast_mm_s = MMM_TO_MMS(Z_PROBE_FEEDRATE_FAST); #endif +#if ENABLED(Z_SAFE_HOMING) + constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; +#endif + /** * Feed rates are often configured with mm/m * but the planner and stepper like mm/s units. @@ -455,6 +459,13 @@ void set_axis_is_at_home(const AxisEnum axis); */ extern main_axes_bits_t axes_homed, axes_trusted; void homeaxis(const AxisEnum axis); + #if ENABLED(CREALITY_RTS) + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + float homeaxis_bl(const AxisEnum axis, const feedRate_t fr_mm_fast=Z_PROBE_FEEDRATE_FAST, const feedRate_t fr_mm_slow=Z_PROBE_FEEDRATE_SLOW); + #else + void homeaxis_bl(const AxisEnum axis); + #endif + #endif void set_axis_never_homed(const AxisEnum axis); main_axes_bits_t axes_should_home(main_axes_bits_t axes_mask=main_axes_mask); bool homing_needed_error(main_axes_bits_t axes_mask=main_axes_mask); diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index 3a8bb2b6c6..6ce9d85c69 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -37,6 +37,9 @@ #include "../gcode/gcode.h" #include "../lcd/marlinui.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif #if HAS_LEVELING #include "../feature/bedlevel/bedlevel.h" @@ -1060,6 +1063,7 @@ float Probe::probe_at_point( // The user may want to quickly move the carriage or bed by hand to avoid bed damage from the (hot) nozzle. // This would also benefit from the contemplated "Audio Alerts" feature. stow(); + TERN_(CREALITY_RTS, RTS_ProbingFailed()); LCD_MESSAGE(MSG_LCD_PROBING_FAILED); #if DISABLED(G29_RETRY_AND_RECOVER) SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED); diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index f0ade99082..8864c38950 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -51,6 +51,10 @@ #include "stepper.h" #include "temperature.h" +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../lcd/marlinui.h" #include "../libs/vector_3.h" // for matrix_3x3 #include "../gcode/gcode.h" @@ -711,6 +715,17 @@ typedef struct SettingsDataStruct { char gcode_macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1]; #endif + // + // Creality RTS + // + #if ENABLED(CREALITY_RTS) + bool wifi_enable_flag; // M194 S + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + float zCoordinateOffset; // RTS Z offset + #endif + float bedNozzleHeightCalZ; + #endif + } SettingsData; //static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!"); @@ -1765,6 +1780,15 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(ui.language); #endif + #if ENABLED(CREALITY_RTS) + _FIELD_TEST(wifi_enable_flag); + EEPROM_WRITE(wifi_enable_flag); + #if ENABLED(BLTOUCH_AND_Z_LIMIT) + EEPROM_WRITE(rts.zCoordinateOffset); // Z轴空间坐标差 + #endif + EEPROM_WRITE(bedNozzleHeightCalZ); // caixiaoliang add 20210807 + #endif + // // Model predictive control // @@ -2900,6 +2924,13 @@ void MarlinSettings::postprocess() { } #endif + #if ENABLED(CREALITY_RTS) + _FIELD_TEST(wifi_enable_flag); + EEPROM_READ(wifi_enable_flag); + EEPROM_READ(rts.zCoordinateOffset); // rock_20220730 + EEPROM_READ(bedNozzleHeightCalZ); // caixiaoliang add 20210807 + #endif + // // Model predictive control // @@ -3690,6 +3721,11 @@ void MarlinSettings::reset() { stepper.set_digipot_current(q, tmp_motor_current_setting[q]); #endif + #if ENABLED(CREALITY_RTS) + ui.language = 1; // 0:Chinese, 1:English + wifi_enable_flag = true; + #endif + // // Adaptive Step Smoothing state // @@ -4185,6 +4221,12 @@ void MarlinSettings::reset() { // MMU3 // TERN_(HAS_PRUSA_MMU3, gcode.MMU3_report(forReplay)); + + #if ENABLED(CREALITY_RTS) + CONFIG_ECHO_HEADING("WIFI Enabled"); + CONFIG_ECHO_MSG(" M194 S", wifi_enable_flag); + //SERIAL_ECHOLNPGM(" rts.zCoordinateOffset ! ", rts.zCoordinateOffset); + #endif } #endif // !DISABLE_M503 diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index f0ca49ef66..d82cfe2b3a 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -54,6 +54,8 @@ #include "../lcd/dwin/creality/dwin.h" #elif ENABLED(SOVOL_SV06_RTS) #include "../lcd/sovol_rts/sovol_rts.h" +#elif ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" #endif #if ENABLED(EXTENSIBLE_UI) @@ -701,7 +703,7 @@ volatile bool Temperature::raw_temps_ready = false; TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Run UI update - #if ENABLED(SOVOL_SV06_RTS) + #if ANY(SOVOL_SV06_RTS, CREALITY_RTS) RTS_Update(); #else ui.update(); @@ -789,7 +791,8 @@ void Temperature::factory_reset() { int cycles = 0; bool heating = true; - millis_t next_temp_ms = millis(), t1 = next_temp_ms, t2 = next_temp_ms; + millis_t next_temp_ms, t1, t2; + next_temp_ms = t1 = t2 = millis(); long t_high = 0, t_low = 0; raw_pid_t tune_pid = { 0, 0, 0 }; @@ -950,11 +953,13 @@ void Temperature::factory_reset() { } else if (ELAPSED(ms, temp_change_ms)) { // Watch timer expired TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); _TEMP_ERROR(heater_id, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, current_temp); } } else if (current_temp < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) { // Heated, then temperature fell too far? TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillRunaway_L, ID_KillRunaway_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_ERR_THERMAL_RUNAWAY, current_temp); } } @@ -970,6 +975,7 @@ void Temperature::factory_reset() { TERN_(EXTENSIBLE_UI, ExtUI::onPIDTuning(ExtUI::pidresult_t::PID_TUNING_TIMEOUT)); TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT))); TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_10 : Error_07)); SERIAL_ECHOPGM(STR_PID_AUTOTUNE); SERIAL_ECHOLNPGM(STR_PID_TIMEOUT); break; } @@ -1677,6 +1683,7 @@ void Temperature::_temp_error( void Temperature::maxtemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_HOTEND || HAS_HEATED_BED TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_11 : Error_08)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(1)); TERN_(EXTENSIBLE_UI, ExtUI::onMaxTempError(heater_id)); #endif @@ -1693,6 +1700,7 @@ void Temperature::maxtemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_TEMP, const celsius_float_t deg)) { #if HAS_HOTEND || HAS_HEATED_BED TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_11 : Error_08)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onMinTempError(heater_id)); #endif @@ -1925,6 +1933,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T const auto deg = degHotend(e); if (deg > temp_range[e].maxtemp) { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_08)); MAXTEMP_ERROR(e, deg); } } @@ -1948,6 +1957,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T start_watching_hotend(e); // If temp reached, turn off elapsed check else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_07)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(e)); _TEMP_ERROR(e, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, temp); @@ -1974,6 +1984,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T const auto deg = degBed(); if (deg > BED_MAXTEMP) { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillBadTemp_L, ID_KillBadTemp_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_08)); MAXTEMP_ERROR(H_BED, deg); } } @@ -1988,6 +1999,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T start_watching_bed(); // If temp reached, turn off elapsed check else { TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillHeat_L, ID_KillHeat_D)); + TERN_(CREALITY_RTS, RTS_Error(Error_10)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(H_BED)); _TEMP_ERROR(H_BED, FPSTR(str_t_heating_failed), MSG_ERR_HEATING_FAILED, deg); @@ -3446,6 +3458,7 @@ void Temperature::init() { case TRRunaway: TERN_(SOVOL_SV06_RTS, rts.gotoPageBeep(ID_KillRunaway_L, ID_KillRunaway_D)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_09 : Error_06)); TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(heater_id)); _TEMP_ERROR(heater_id, FPSTR(str_t_thermal_runaway), MSG_ERR_THERMAL_RUNAWAY, current); @@ -3454,6 +3467,7 @@ void Temperature::init() { #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) case TRMalfunction: TERN_(DWIN_CREALITY_LCD, dwinPopupTemperature(0)); + TERN_(CREALITY_RTS, RTS_Error(heater_id == H_BED ? Error_09 : Error_06)); TERN_(EXTENSIBLE_UI, ExtUI::onHeatingError(heater_id)); _TEMP_ERROR(heater_id, F(STR_T_THERMAL_MALFUNCTION), MSG_ERR_TEMP_MALFUNCTION, current); break; @@ -4498,9 +4512,25 @@ void Temperature::isr() { #if HAS_TEMP_HOTEND print_heater_state(H_NONE, degHotend(target_extruder), degTargetHotend(target_extruder) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(target_extruder))); #endif + #if HAS_HEATED_BED - print_heater_state(H_BED, degBed(), degTargetBed() OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #if ENABLED(BED_TEMP_COMP) + celsius_float_t bedDisp = degBed(); + celsius_float_t bedTargetDisp = degTargetBed(); + if (degTargetBed() > 65 && degTargetBed() <= 86) { + bedDisp -= (5 * bedDisp) / degTargetBed(); + bedTargetDisp -= 5; + } + else if (degTargetBed() > 86 && degTargetBed() <= 127) { + bedDisp -= (7 * bedDisp) / degTargetBed(); + bedTargetDisp -= 7; + } + print_heater_state(H_BED, bedDisp, bedTargetDisp OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #else + print_heater_state(H_BED, degBed(), degTargetBed() OPTARG(SHOW_TEMP_ADC_VALUES, rawBedTemp())); + #endif #endif + #if HAS_TEMP_CHAMBER print_heater_state(H_CHAMBER, degChamber(), TERN0(HAS_HEATED_CHAMBER, degTargetChamber()) OPTARG(SHOW_TEMP_ADC_VALUES, rawChamberTemp())); #endif @@ -4522,7 +4552,7 @@ void Temperature::isr() { #if HAS_MULTI_HOTEND HOTEND_LOOP() print_heater_state((heater_id_t)e, degHotend(e), degTargetHotend(e) OPTARG(SHOW_TEMP_ADC_VALUES, rawHotendTemp(e))); #endif - SString<100> s(F(" @:"), getHeaterPower((heater_id_t)target_extruder)); + SString<120> s(F(" @:"), getHeaterPower((heater_id_t)target_extruder)); TERN_(HAS_HEATED_BED, s.append(F(" B@:"), getHeaterPower(H_BED))); TERN_(PELTIER_BED, s.append(F(" P@:"), temp_bed.peltier_dir_heating ? 'H' : 'C')); TERN_(HAS_HEATED_CHAMBER, s.append(F(" C@:"), getHeaterPower(H_CHAMBER))); @@ -4530,6 +4560,10 @@ void Temperature::isr() { #if HAS_MULTI_HOTEND HOTEND_LOOP() s.append(F(" @"), e, ':', getHeaterPower((heater_id_t)e)); #endif + #if ENABLED(CREALITY_CLOUD) + TERN_(HAS_FAN0, s.append(F(" FAN0@:"), thermalManager.fan_speed[0])); + TERN_(HAS_FAN1, s.append(F(" FAN1@:"), thermalManager.fan_speed[1])); + #endif s.echo(); } @@ -4573,6 +4607,7 @@ void Temperature::isr() { #define MIN_COOLING_SLOPE_TIME 60 #endif + //static int s_cnt = 0; bool Temperature::wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling/*=true*/ OPTARG(G26_CLICK_CAN_CANCEL, const bool click_to_cancel/*=false*/) ) { @@ -4604,6 +4639,7 @@ void Temperature::isr() { millis_t now, next_temp_ms = 0, cool_check_ms = 0; for (marlin.heatup_start(); marlin.is_heating() && TEMP_CONDITIONS; ) { // Target temperature might be changed during the loop + //if (!(++s_cnt % 200)) SERIAL_ECHOLN("wait_for_hotend"); if (target_temp != degTargetHotend(target_extruder)) { wants_to_cool = isCoolingHotend(target_extruder); target_temp = degTargetHotend(target_extruder); @@ -4687,6 +4723,8 @@ void Temperature::isr() { update_time_value = RTS_UPDATE_VALUE; if (card.isStillPrinting()) rts.refreshTime(); rts.start_print_flag = false; + #elif ENABLED(CREALITY_RTS) + update_time_value = RTS_UPDATE_VALUE; #else ui.reset_status(); #endif @@ -4798,6 +4836,7 @@ void Temperature::isr() { millis_t now, next_temp_ms = 0, cool_check_ms = 0; marlin.heatup_start(); do { + //if (!(++s_cnt % 200)) SERIAL_ECHOLN("wait_for_bed"); // Target temperature might be changed during the loop if (target_temp != degTargetBed()) { wants_to_cool = isCoolingBed(); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 426437d9d1..8a41043412 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -41,6 +41,10 @@ #include "../lcd/sovol_rts/sovol_rts.h" #endif +#if ENABLED(CREALITY_RTS) + #include "../lcd/rts/lcd_rts.h" +#endif + #include "../module/planner.h" // for synchronize #include "../module/printcounter.h" #include "../gcode/queue.h" @@ -485,6 +489,7 @@ void CardReader::printSelectedFilename() { } void CardReader::mount() { + delay(5); flag.mounted = false; nrItems = -1; if (root.isOpen()) root.close(); @@ -1665,6 +1670,8 @@ void CardReader::fileHasFinished() { flag.sdprintdone = true; // Stop getting bytes from the SD card marlin.setState(MF_SD_COMPLETE); // Tell Marlin to enqueue M1001 soon + + TERN_(CREALITY_RTS, RTS_SDFileCompleted()); } #if ENABLED(AUTO_REPORT_SD_STATUS) diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp index fde697c1f4..b1ba710932 100644 --- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp +++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp @@ -22,6 +22,10 @@ #include "../../inc/MarlinConfigPre.h" +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../feature/powerloss.h" +#endif + /** * Adjust USB_DEBUG to select debugging verbosity. * 0 - no debug messages @@ -229,7 +233,16 @@ void DiskIODriver_USBFlash::idle() { } break; - case MEDIA_READY: break; + case MEDIA_READY: + #if ENABLED(POWER_LOSS_RECOVERY) + static bool firstStart = false; + if (!firstStart) { + firstStart = true; + recovery.check(); + } + #endif + break; + case MEDIA_ERROR: break; }